package com.xbongbong.paas.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.outLink.domain.entity.OuterLinkConfigEntity;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.FieldPermissionEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.ComboTypeEnum;
import com.xbongbong.paas.enums.DefaultTypeEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.RelatedPersonnelEnum;
import com.xbongbong.paas.enums.StarEnum;
import com.xbongbong.paas.enums.TitleSupportFieldEnum;
import com.xbongbong.paas.enums.VisibleTypeEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkFormPoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.field.VisibleRulePoJo;
import com.xbongbong.paas.field.VisibleRuleVO;
import com.xbongbong.paas.pojo.DetailTabPojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.OperationsPojo;
import com.xbongbong.paas.pojo.OutLinkFieldAttrEntity;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.DepartmentVO;
import com.xbongbong.paas.toolbox.wrap.RoleSimpleVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.domain.entity.UpdateDataValueEntity;
import com.xbongbong.pro.domain.entity.UpdateSubDataEntity;
import com.xbongbong.pro.enums.AmountFlagEnum;
import com.xbongbong.pro.enums.DataTypeEnum;
import com.xbongbong.pro.enums.FieldAdvanceOperationEnum;
import com.xbongbong.pro.enums.HideEditableEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.label.pojo.LabelPojo;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.OnlineEditorConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.SaasEditAttrConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderEntityExt;
import com.xbongbong.saas.enums.NumberTypeEnum;
import com.xbongbong.saas.enums.OuterLinkTypeEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.VisibleRangeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.ContractOutstockEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.business.WorkReportDailyEnum;
import com.xbongbong.saas.enums.business.WorkReportMonthlyEnum;
import com.xbongbong.saas.enums.business.WorkReportWeeklyEnum;
import com.xbongbong.saas.enums.product.BusinessProductCompareEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author: wufeng
 * @date: 2018/10/16 17:06
 * @desrcption: 字段列表工具类
 */
public class ExplainUtil {

    private static final Logger LOG = LoggerFactory.getLogger(ExplainUtil.class);

    private static final String ZERO = "0";

    /**
     * 获取摘要、标签、标题的值
     * @param formDataESListVO
     * @param formMap formId和form的map，目前仅用于工单全部列表，用于渲染摘要，标签，标题
     * @param formIdAndHeadListMap formId和explain（过滤后的）的map，目前仅用于工单全部列表，用于渲染摘要，标签，标题，与上面一个参数必须一起传
     * @return
     * @throws XbbException
     */
    public static PaasFormDataEsListVO getValueByData(PaasFormDataEsListVO formDataESListVO, Map<Long, PaasFormEntityExt> formMap, Map<Long, List<FieldAttrEntity>> formIdAndHeadListMap) throws XbbException{
        PaasFormDataEsListVO paasFormDataEsListVO = new PaasFormDataEsListVO();

        try {
            List<PaasFormDataEntityExt>  paasFormDataESList = formDataESListVO.getPaasFormDataESList();
            if (Objects.isNull(formMap) && Objects.isNull(formIdAndHeadListMap)) {
                Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                List<FieldAttrEntity> explainList = formDataESListVO.getHeadList();
                for (FieldAttrEntity fieldAttrEntity: explainList) {
                    explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                }
                // 获取摘要
                JSONArray summaryList = formDataESListVO.getForm().getSummaryList();
                paasFormDataESList = getValueByAttr(paasFormDataESList, explainMap, summaryList, "summaryList");

                // 获取标签
                JSONArray labelsList = formDataESListVO.getForm().getLabelsList();
                paasFormDataESList = getValueByAttr(paasFormDataESList, explainMap, labelsList, "labelsList");
                // 获取标题
                JSONArray titleList = JSONArray.parseArray(formDataESListVO.getForm().getCustomTitle());
                paasFormDataESList = getTitleByAttr(paasFormDataESList, explainMap, titleList, explainList);
            } else {
                if (Objects.nonNull(formMap)) {
                    for (PaasFormDataEntityExt formDataEntityExt : paasFormDataESList) {
                        Long formId = formDataEntityExt.getFormId();
                        JSONObject data = formDataEntityExt.getData();
                        PaasFormEntityExt paasFormEntityExt = formMap.get(formId);
                        paasFormEntityExt.setSummaryList(paasFormEntityExt.getSummary());
                        paasFormEntityExt.setLabelsList(paasFormEntityExt.getLabels());
                        paasFormEntityExt.setCustomTitle(paasFormEntityExt.getCustomTitle());
                        List<FieldAttrEntity> headList = formIdAndHeadListMap.get(formId);
                        Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        for (FieldAttrEntity fieldAttrEntity: headList) {
                            explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                        }
                        // 获取摘要
                        JSONArray summaryArray = paasFormEntityExt.getSummaryList();
                        List<SummaryDataPoJo> summaryList = getSummaryList(summaryArray, data, explainMap, formDataEntityExt);
                        data.put("summaryList", summaryList);
                        // 获取标签
                        JSONArray labelsArray = paasFormEntityExt.getLabelsList();
                        List<SummaryDataPoJo> labelsList = getSummaryList(labelsArray, data, explainMap, formDataEntityExt);
                        data.put("labelsList", labelsList);
                        // 获取标题
                        JSONArray titleList = JSONArray.parseArray(paasFormEntityExt.getCustomTitle());
                        List<FormTitlePoJo> formTitleList = getFormTitle(titleList, explainMap, data, headList, formDataEntityExt);
                        data.put("titleList", formTitleList);
                        formDataEntityExt.setData(data);
                    }
                }
            }
            BeanUtil.copyProperties(formDataESListVO, paasFormDataEsListVO);
            paasFormDataEsListVO.setPaasFormDataESList(paasFormDataESList);
        } catch (Exception e){
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paasFormDataEsListVO;
    }

    /**
     * 根据attr获取attrName和value值
     * @param paasFormDataESList 数据
     * @param explainMap 字段集合
     * @param titleList 标题列表
     * @param explainList 字段列表
     * @return
     */
    public static List<PaasFormDataEntityExt> getTitleByAttr(List<PaasFormDataEntityExt>  paasFormDataESList,
                                                            Map<String, FieldAttrEntity> explainMap, JSONArray titleList, List<FieldAttrEntity> explainList) throws XbbException{
        try {

            for (int i = 0; i < paasFormDataESList.size(); i++) {
                PaasFormDataEntityExt formData = paasFormDataESList.get(i);
                JSONObject data = formData.getData();
                List<FormTitlePoJo> formTitleList = getFormTitle(titleList, explainMap, data, explainList, formData);
                data.put("titleList", formTitleList );
                paasFormDataESList.get(i).setData(data);
            }

        } catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paasFormDataESList;
    }

    /**
     * 根据attr获取attrName和value值
     * @param paasFormDataESList 数据
     * @param explainMap 字段集合
     * @param titleList 标题列表
     * @param explainList 字段列表
     * @return
     */
    public static List<WorkOrderEntityExt> getTitleFromAttr(List<WorkOrderEntityExt>  paasFormDataESList,
                                                             Map<String, FieldAttrEntity> explainMap, JSONArray titleList, List<FieldAttrEntity> explainList) throws XbbException{
        try {

            for (int i = 0; i < paasFormDataESList.size(); i++) {
                PaasFormDataEntityExt formData = paasFormDataESList.get(i);
                JSONObject data = formData.getData();
                List<FormTitlePoJo> formTitleList = getFormTitle(titleList, explainMap, data, explainList, formData);
                data.put("titleList", formTitleList );
                paasFormDataESList.get(i).setData(data);
            }

        } catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paasFormDataESList;
    }

    /**
     * 根据attr获取attrName和value值
     * @param titleList 标题列表
     * @param explainMap 字段集合
     * @param data 单行数据
     * @param explainList 字段列表
     * @return
     * @throws XbbException
     */
    public static List<FormTitlePoJo> getFormTitle(JSONArray titleList, Map<String, FieldAttrEntity> explainMap, JSONObject data, List<FieldAttrEntity> explainList, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException{
        List<FormTitlePoJo> formTitleList = new ArrayList<>();
        try {
            if(titleList == null || titleList.isEmpty()) {
                // 标题为空，则用第一个字段为标题
                for(FieldAttrEntity fieldAttrEntity : explainList) {
                    FormTitlePoJo formTitlePoJo = new FormTitlePoJo();
                    if(data.containsKey(fieldAttrEntity.getAttr()) && Objects.equals(1, fieldAttrEntity.getVisible()) && TitleSupportFieldEnum.isHasNeedFilterField(fieldAttrEntity.getFieldType())){
                        String attr = fieldAttrEntity.getAttr();
                        formTitlePoJo.setAttrName(fieldAttrEntity.getAttrName());
                        List<Object> list = getDataList(fieldAttrEntity, data, paasFormDataEntityExt);
                        formTitlePoJo.setValue(list);
                        formTitlePoJo.setAttr(attr);
                        formTitleList.add(formTitlePoJo);
                        break;
                    }
                }
            } else {
                for (int j = 0; j < titleList.size(); j++) {
                    FormTitlePoJo formTitlePoJo = JSON.toJavaObject(titleList.getJSONObject(j), FormTitlePoJo.class);
                    String attr = formTitlePoJo.getAttr();
                    if (StringUtil.isEmpty(formTitlePoJo.getContent())) {
                        FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                        if(fieldAttrEntity!= null && Objects.equals(1, fieldAttrEntity.getVisible())){
                            List<Object> list = getDataList(fieldAttrEntity, data, paasFormDataEntityExt);
                            formTitlePoJo.setValue(list);
                            formTitlePoJo.setAttrName(fieldAttrEntity.getAttrName());
                            formTitleList.add(formTitlePoJo);
                        }
                    }else {
                        formTitlePoJo.setValue(Arrays.asList(formTitlePoJo.getContent()));
                        formTitleList.add(formTitlePoJo);
                    }
                }
            }
        }catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formTitleList;
    }

    /**
     * Description: 根据attr获取attrName和value值(详情专用)
     * @param titleList
     * @param explainMap
     * @param data
     * @param explainList
     * @param paasFormDataEntityExt
     * @throws XbbException
     * @author 刘阳
     * @date 2019/7/5 7:55 PM
     * @since v1.0
     */
    public static List<FormTitlePoJo> getSpecailFormTitle(JSONArray titleList, Map<String, FieldAttrEntity> explainMap, JSONObject data, List<FieldAttrEntity> explainList, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException{
        List<FormTitlePoJo> formTitleList = new ArrayList<>();
        try {
            if(titleList == null || titleList.isEmpty()) {
                // 标题为空，则用第一个字段为标题
                for(FieldAttrEntity fieldAttrEntity : explainList) {
                    FormTitlePoJo formTitlePoJo = new FormTitlePoJo();
                    if(data.containsKey(fieldAttrEntity.getAttr()) && Objects.equals(1, fieldAttrEntity.getVisible()) && TitleSupportFieldEnum.isHasNeedFilterField(fieldAttrEntity.getFieldType())){
                        String attr = fieldAttrEntity.getAttr();
                        formTitlePoJo.setAttrName(fieldAttrEntity.getAttrName());
                        List<Object> list = getDataList(fieldAttrEntity, data, paasFormDataEntityExt);
                        formTitlePoJo.setValue(list);
                        formTitlePoJo.setAttr(attr);
                        formTitleList.add(formTitlePoJo);
                        break;
                    }
                }
            } else {
                for (int j = 0; j < titleList.size(); j++) {
                    FormTitlePoJo formTitlePoJo = JSON.toJavaObject(titleList.getJSONObject(j), FormTitlePoJo.class);
                    String attr = formTitlePoJo.getAttr();
                    if (StringUtil.isEmpty(formTitlePoJo.getContent())) {
                        FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                        if(fieldAttrEntity!= null && Objects.equals(1, fieldAttrEntity.getVisible())){
                            List<Object> list = getSpecialDataList(fieldAttrEntity, data, paasFormDataEntityExt);
                            formTitlePoJo.setValue(list);
                            formTitlePoJo.setAttrName(fieldAttrEntity.getAttrName());
                            formTitleList.add(formTitlePoJo);
                        }
                    }else {
                        formTitleList.add(formTitlePoJo);
                    }
                }
            }
        }catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formTitleList;
    }

    /**
     * Description: 根据attr获取attrName和value值(工单独有)
     * @param titleList 标题列表
     * @param explainMap 字段集合
     * @param data 单行数据
     * @param explainList 字段列表
     * @throws XbbException
     * @author 刘阳
     * @date 2019/5/10 9:33 AM
     * @since v1.0
     */
    public static List<FormTitlePoJo> getWorkOrderFormTitle(JSONArray titleList, Map<String, FieldAttrEntity> explainMap, JSONObject data, List<FieldAttrEntity> explainList, WorkOrderEntity workOrderEntity) throws XbbException{
        List<FormTitlePoJo> formTitleList = new ArrayList<>();
        try {
            if(titleList == null || titleList.isEmpty()) {
                // 判断工单名称是否存在，否则赋值工单编号
                if (data.containsKey(WorkOrderEnum.NAME.getAttr())) {
                    String attr = WorkOrderEnum.NAME.getAttr();
                    FormTitlePoJo formTitlePoJo = new FormTitlePoJo();
                    formTitlePoJo.setAttrName(WorkOrderEnum.NAME.getAttrName());
                    formTitlePoJo.setValue(Collections.singletonList(data.get(attr)));
                    formTitlePoJo.setAttr(attr);
                    formTitleList.add(formTitlePoJo);
                } else {
                    FormTitlePoJo formTitlePoJo = new FormTitlePoJo();
                    if (Objects.nonNull(workOrderEntity) && StringUtil.isNotEmpty(workOrderEntity.getSerialNo())) {
                        formTitlePoJo.setValue(Collections.singletonList(workOrderEntity.getSerialNo()));
                        formTitlePoJo.setAttrName(FieldTypeEnum.SERIALNO.getDescription());
                        formTitlePoJo.setAttr("serialNo");
                        formTitleList.add(formTitlePoJo);
                    }
                }
            } else {
                for (int j = 0; j < titleList.size(); j++) {
                    FormTitlePoJo formTitlePoJo = JSON.toJavaObject(titleList.getJSONObject(j), FormTitlePoJo.class);
                    String attr = formTitlePoJo.getAttr();
                    if (StringUtil.isEmpty(formTitlePoJo.getContent())) {
                        FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                        if(fieldAttrEntity!= null && Objects.equals(1, fieldAttrEntity.getVisible())){
                            List<Object> list = getSpecialDataList(fieldAttrEntity, data, workOrderEntity);
                            formTitlePoJo.setValue(list);
                            formTitlePoJo.setAttrName(fieldAttrEntity.getAttrName());
                            formTitleList.add(formTitlePoJo);
                        }
                    }else {
                        formTitleList.add(formTitlePoJo);
                    }
                }
            }
        }catch (Exception e) {
            LOG.error("WorkOrderDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formTitleList;
    }
    /**
     * 获取摘要或者标签的标题和value值
     * @param paasFormDataESList 数据
     * @param explainMap 字段集合
     * @param jsonArray 摘要或者标签列表
     * @param key 摘要或者标签的key值
     * @return
     */
    public static List<PaasFormDataEntityExt> getValueByAttr(List<PaasFormDataEntityExt>  paasFormDataESList, Map<String, FieldAttrEntity> explainMap, JSONArray jsonArray, String key) throws XbbException{
        try {
            if (jsonArray != null) {
                for (int i = 0; i < paasFormDataESList.size(); i++) {
                    PaasFormDataEntityExt formData = paasFormDataESList.get(i);
                    JSONObject data = formData.getData();
                    List<SummaryDataPoJo> summaryList = getSummaryList(jsonArray, data, explainMap, formData);
                    data.put(key, summaryList);
                    paasFormDataESList.get(i).setData(data);
                }
            }
        } catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paasFormDataESList;
    }

    /**
     * 获取摘要或者标签的标题和value值
     * @param paasFormDataESList 数据
     * @param explainMap 字段集合
     * @param jsonArray 摘要或者标签列表
     * @param key 摘要或者标签的key值
     * @return
     */
    public static List<WorkOrderEntityExt> getValueFromAttr(List<WorkOrderEntityExt>  paasFormDataESList, Map<String, FieldAttrEntity> explainMap, JSONArray jsonArray, String key) throws XbbException{
        try {
            if (jsonArray != null) {
                for (int i = 0; i < paasFormDataESList.size(); i++) {
                    WorkOrderEntityExt formData = paasFormDataESList.get(i);
                    JSONObject data = formData.getData();
                    List<SummaryDataPoJo> summaryList = getSummaryList(jsonArray, data, explainMap, formData);
                    data.put(key, summaryList);
                    paasFormDataESList.get(i).setData(data);
                }
            }
        } catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paasFormDataESList;
    }

    /**
     * 获取摘要或者标签的标题和value值
     * @param jsonArray 摘要或者标签列表
     * @param data 单行数据
     * @param explainMap 列表集合
     * @return
     */
    public static List<SummaryDataPoJo> getSummaryDataList(JSONArray jsonArray, JSONObject data, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException{
        List<SummaryDataPoJo> summaryList = new ArrayList<>();
        try {
            for (int j = 0; j < jsonArray.size(); j++) {
                SummaryDataPoJo summary = JSON.toJavaObject(jsonArray.getJSONObject(j), SummaryDataPoJo.class);
                String attr = summary.getAttr();
                if (data.containsKey(attr)) {
                    FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                    if(fieldAttrEntity != null) {
                        Object attrValue = data.get(attr);
                        List<Object> list = new ArrayList<>();
                        if(attrValue instanceof ArrayList || attrValue instanceof JSONArray){
                            List tempList = (List<Object>) attrValue;
                            if (FieldTypeEnum.COMBO_CHECK.getType().equals(fieldAttrEntity.getFieldType())
                                    || FieldTypeEnum.CHECKBOX_GROUP.getType().equals(fieldAttrEntity.getFieldType())) {
                                for(Object object : tempList) {
                                    for (ItemPoJo itemPoJo : fieldAttrEntity.getItems()) {
                                        if (Objects.equals(object.toString(), itemPoJo.getValue())) {
                                            list.add(itemPoJo.getText());
                                        }
                                    }
                                }
                            } else {
                                list.addAll(tempList);
                            }
                        }else{
                            String[] attrArray = attr.split("_");
                            if (FieldTypeEnum.BIRTHDAY.getType().equals(summary.getFieldType())) {
                                list.add(data.getJSONObject(attr).getString(StringConstant.VALUE));
                            } else if(FieldTypeEnum.DATETIME.getEsalias().equals(attrArray[0])){
                                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(explainMap.get(attr).getDateType());
                                Long dateTime = data.getLong(attr);
                                if (dateTime != null && dateTime != 0) {
                                    list.add(DateTimeUtil.getStringEpochSecond(dateTime, simpleDateFormat));
                                }
                            } else if (FieldTypeEnum.COMBO.getType().equals(fieldAttrEntity.getFieldType())
                                        || FieldTypeEnum.RADIO_GROUP.getType().equals(fieldAttrEntity.getFieldType())) {
                                Object type = ItemUtil.getCustomItemList(fieldAttrEntity, data);
                                if (Objects.nonNull(type)) {
                                    list.add(type);
                                }
                            } else if (FieldTypeEnum.ADDTIME.getType().equals(fieldAttrEntity.getFieldType())
                                    || FieldTypeEnum.UPDATETIME.getType().equals(fieldAttrEntity.getFieldType())) {
                                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(explainMap.get(attr).getDateType());
                                Long dateTime = data.getLong(attr);
                                if (dateTime != null && dateTime != 0) {
                                    list.add(DateTimeUtil.getStringEpochSecond(dateTime, simpleDateFormat));
                                }
                            } else if(FieldTypeEnum.NUM.getType().equals(fieldAttrEntity.getFieldType())){
                                String pattern;
                                if(AmountFlagEnum.YES.getType().equals(fieldAttrEntity.getAmountFlag())){
                                    //待优化
                                    pattern = "##,##0.";
                                }else {
                                    pattern = "##0.";
                                }
                                for (int i = 0; i < fieldAttrEntity.getAccuracy(); i++) {
                                    pattern = pattern + "0";
                                }
                                DecimalFormat df = new DecimalFormat(pattern);
                                list.add(df.format(Double.parseDouble(data.getString(attr))));
                            }else{
                                list.add(data.get(attr));
                            }
                        }
                        summary.setValue(list);
                        summary.setAttrName(fieldAttrEntity.getAttrName());
                        summaryList.add(summary);
                    }
                } else {
                    // SERIALNO字段不存放在data数据中
                    if (Objects.equals(attr, FieldTypeEnum.SERIALNO.getAlias()) && Objects.nonNull(paasFormDataEntityExt) && StringUtil.isNotEmpty(paasFormDataEntityExt.getSerialNo())) {
                        summary.setValue(Collections.singletonList(paasFormDataEntityExt.getSerialNo()));
                        summary.setAttrName(FieldTypeEnum.SERIALNO.getDescription());
                        summaryList.add(summary);
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return summaryList;
    }

    /**
     * 获取详情摘要数据
     *
     * @param isTeam 是否为负责人
     * @param name   名称
     * @param value  值
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-04-26 17:36
     * @version v1.0
     * @since v1.0
     */
    public static JSONObject getSecondTitleObj(boolean isTeam, String name, Object value) {
        return getSecondTitleObj(isTeam,   name,   value,null);
    }

    public static JSONObject getSecondTitleObj(boolean isTeam, String name, Object value,String type) {
        JSONObject object = new JSONObject();
        String typeStr = isTeam ? "tooltip" : "normal";
        if(StringUtil.isNotEmpty(type)){
            typeStr = type;
        }
        object.put("type", typeStr);
        object.put("name", name);
        object.put("value", value);
        return object;
    }
    /**
     * 获取字段集合
     * @param explain
     * @return
     */
    public static Map<String, FieldAttrEntity> getExplainMap(String explain, String attr){
        List<FieldAttrEntity> fieldList = JSONArray.parseArray(explain, FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(FieldAttrEntity fieldAttrEntity: fieldList){
            explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
            if (attr != null && fieldAttrEntity.getAttr().equals(attr)) {
                break;
            }
        }
        return explainMap;
    }

    /**
     * 根据fieldType去拿FieldAttrEntity 仅限explain中此fieldType唯一才能使用， 慎用
     * @param explain
     * @param fieldType
     * @return
     */
    public static FieldAttrEntity getFieldWithFieldType(String explain, Integer fieldType){
        List<FieldAttrEntity> fieldList = JSONArray.parseArray(explain, FieldAttrEntity.class);
        FieldAttrEntity fieldAttrEntity = null;
        for (FieldAttrEntity field : fieldList) {
            if (Objects.equals(field.getFieldType(), fieldType)) {
                fieldAttrEntity = field;
                break;
            }
        }
        return fieldAttrEntity;
    }

    /**
     * 通过字段类型获取字段解释
     *
     * @param fieldList 字段解释
     * @param fieldType 字段类型
     * @return FieldAttrEntity
     */
    public static FieldAttrEntity getFieldWithFieldType(List<FieldAttrEntity> fieldList, Integer fieldType){
        return fieldList.stream().filter(field -> Objects.equals(field.getFieldType(), fieldType)).findFirst().orElse(null);
    }

    public static Map<String, FieldAttrEntity> getExplainAndDataIdMap(String explain, String attr){
        Map<String, FieldAttrEntity> explainMap = getExplainMap(explain, attr);
        setDataIdField(explainMap);
        return explainMap;
    }

    public static void setDataIdField(Map<String, FieldAttrEntity> explainMap) {
        FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
        fieldAttrEntity.setAttr(FieldTypeEnum.DATAID.getAlias());
        fieldAttrEntity.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.SELECTED_DATA));
        fieldAttrEntity.setFieldType(FieldTypeEnum.DATAID.getType());
        explainMap.put(FieldTypeEnum.DATAID.getAlias(), fieldAttrEntity);
    }

    /**
     * 获取字段集合MAP,包括子表单内的attr，用attr.subAttr
     * @param explain
     * @return
     */
    public static Map<String, FieldAttrEntity> getExplainMap(String explain){
        List<FieldAttrEntity> fieldList = JSONArray.parseArray(explain, FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(FieldAttrEntity fieldAttrEntity: fieldList){
            String attr = fieldAttrEntity.getAttr();
            explainMap.put(attr, fieldAttrEntity);
            if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.SUB_FORM.getType())) {
                List<? extends FieldAttrEntity> subExplainList = fieldAttrEntity.getSubForm().getItems();
                for (FieldAttrEntity subAttrEntity : subExplainList) {
                    String key = attr + StringConstant.POINT + subAttrEntity.getAttr();
                    subAttrEntity.setAttrName(fieldAttrEntity.getAttrName() + StringConstant.POINT + subAttrEntity.getAttrName());
                    explainMap.put(key, subAttrEntity);
                }
            }
        }
        return explainMap;
    }

    /**
     * 获取字段集合MAP,包括所有子表单内的attr，比如关联产品子表单等，用attr.subAttr
     * @param explain
     * @return
     */
    public static Map<String, FieldAttrEntity> getAllSubFormExplainMap(String explain){
        List<FieldAttrEntity> fieldList = JSONArray.parseArray(explain, FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = getSubFormExplainMapByList(fieldList);
        return explainMap;
    }

    /**
     * 获取字段集合MAP,包括所有子表单内的attr，比如关联产品子表单等，用attr.subAttr
     * @param fieldList
     * @return
     */
    public static Map<String, FieldAttrEntity> getSubFormExplainMapByList(List<FieldAttrEntity> fieldList){
        Map<String, FieldAttrEntity> explainMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(FieldAttrEntity fieldAttrEntity: fieldList){
            String attr = fieldAttrEntity.getAttr();
            explainMap.put(attr, fieldAttrEntity);
            if (isSubForm(fieldAttrEntity.getFieldType())) {
                if (Objects.nonNull(fieldAttrEntity.getSubForm())) {
                    List<? extends FieldAttrEntity> subExplainList = fieldAttrEntity.getSubForm().getItems();
                    if (CollectionsUtil.isNotEmpty(subExplainList)) {
                        for (FieldAttrEntity subAttrEntity : subExplainList) {
                            String key = attr + StringConstant.POINT + subAttrEntity.getAttr();
                            explainMap.put(key, subAttrEntity);
                        }
                    }
                }
            }
        }
        return explainMap;
    }


    /**
     * 获取字段集合
     * @param explain
     * @return
     */
    public static Map<String, FieldAttrEntity> getExplainMapByAttr(String explain, String attr) throws XbbException{
        if (StringUtil.isEmpty(attr)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
        }
        List<FieldAttrEntity> fieldList = JSONArray.parseArray(explain, FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(FieldAttrEntity fieldAttrEntity: fieldList){
            if(fieldAttrEntity.getAttr().equals(attr) && StringUtil.isNotEmpty(attr)){
                explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                break;
            }
        }
        return explainMap;
    }

    /**
     * 根据attrList获取字段集合
     * @param explain
     * @return explainMap
     */
    public static Map<String, FieldAttrEntity> getExplainMapByAttrList(String explain, List<String> attrList) throws XbbException{
        if (attrList.isEmpty()) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,  MessageConstant.CAN_NOT_BE_EMPTY, "attrList");
        }

        Map<String, FieldAttrEntity> res = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        List<FieldAttrEntity> fieldList = JSONArray.parseArray(explain, FieldAttrEntity.class);
        for(FieldAttrEntity fieldAttrEntity: fieldList){
            for (String attr : attrList) {
                if (Objects.isNull(attr) || StringUtil.isEmpty(attr)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.CAN_NOT_BE_EMPTY, "attr");
                }
                if (Objects.equals(attr, fieldAttrEntity.getAttr())) {
                    res.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                }
            }
        }
        return res;
    }

    /**
     * 根据attrList获取字段集合
     * @param fieldList
     * @return explainMap
     */
    public static Map<String, FieldAttrEntity> getExplainMapByAttrList(List<FieldAttrEntity> fieldList, List<String> attrList) throws XbbException{
        if (attrList.isEmpty()) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,  MessageConstant.CAN_NOT_BE_EMPTY, "attrList");
        }

        Map<String, FieldAttrEntity> res = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        for(FieldAttrEntity fieldAttrEntity: fieldList){
            for (String attr : attrList) {
                if (Objects.isNull(attr) || StringUtil.isEmpty(attr)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.CAN_NOT_BE_EMPTY, "attr");
                }
                if (Objects.equals(attr, fieldAttrEntity.getAttr())) {
                    res.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                }
            }
        }
        return res;
    }

    /**
     * 获取字段集合
     * @param explain
     * @return
     */
    public static Map<String, FieldAttrEntityForImport> getExplainMapForImport(String explain, String attr){
        List<FieldAttrEntityForImport> fieldList = JSONArray.parseArray(explain, FieldAttrEntityForImport.class);
        Map<String, FieldAttrEntityForImport> explainMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(FieldAttrEntityForImport fieldAttrEntityForImport: fieldList){
            if(fieldAttrEntityForImport.getAttr().equals(attr)){
                explainMap.put(fieldAttrEntityForImport.getAttr(), fieldAttrEntityForImport);
                break;
            }else{
                explainMap.put(fieldAttrEntityForImport.getAttr(), fieldAttrEntityForImport);
            }
        }
        return explainMap;
    }

    public static Map<String, FieldAttrEntity> getExplainMapByList(List<FieldAttrEntity> fieldList, String attr){
        Map<String, FieldAttrEntity> explainMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(FieldAttrEntity fieldAttrEntity: fieldList){
            if(fieldAttrEntity.getAttr().equals(attr)){
                explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                break;
            }else {
                explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
            }
        }
        return explainMap;
    }

    public static Map<String, FieldAttrEntity> getExplainMapByList(List<? extends FieldAttrEntity> fieldList){
        Map<String, FieldAttrEntity> explainMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionsUtil.isEmpty(fieldList)) {
            return explainMap;
        }
        for(FieldAttrEntity fieldAttrEntity: fieldList){
            explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
        }
        return explainMap;
    }

    /**
     * 获取摘要或者标签的标题和value值
     * @param jsonArray 摘要或者标签列表
     * @param data 单行数据
     * @param explainMap 列表集合
     * @return
     */
    public static List<SummaryDataPoJo> getSummaryList(JSONArray jsonArray, JSONObject data, Map<String, FieldAttrEntity> explainMap,
                                                           PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException{
        List<SummaryDataPoJo> summaryList = new ArrayList<>();
        try {
            if (Objects.isNull(jsonArray)) {
                return summaryList;
            }
            for (int j = 0; j < jsonArray.size(); j++) {
                SummaryDataPoJo summary = JSON.toJavaObject(jsonArray.getJSONObject(j), SummaryDataPoJo.class);
                String attr = summary.getAttr();

                FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                if (Objects.isNull(fieldAttrEntity) && attr.indexOf(BusinessConstant.ADDRESS) > -1) {
                    fieldAttrEntity = explainMap.get(attr+StringConstant.POINT+BusinessConstant.ADDRESS);
                }
                if(Objects.isNull(fieldAttrEntity) || Objects.equals(0, fieldAttrEntity.getVisible()) || Objects.equals(0, fieldAttrEntity.getIsOpen())) {
                    continue;
                }
                List<Object> list = getDataList(fieldAttrEntity, data, paasFormDataEntityExt);
                summary.setFieldType(fieldAttrEntity.getFieldType());
                summary.setValue(list);
                summary.setAttrName(fieldAttrEntity.getAttrName());
                summaryList.add(summary);
            }
        } catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return summaryList;
    }

    /**
     * Description:
     * @param jsonArray
     * @param data
     * @param explainMap
     * @author 刘阳
     * @date 2019/7/4 3:59 PM
     * @since v1.0
     */
    public static List<SummaryDataPoJo> getSpecialSummaryList(JSONArray jsonArray, JSONObject data, Map<String, FieldAttrEntity> explainMap,
                                                              PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException{
        List<SummaryDataPoJo> summaryList = new ArrayList<>();
        try {
            if(jsonArray == null ){
                return summaryList;
            }
            for (int j = 0; j < jsonArray.size(); j++) {
                SummaryDataPoJo summary = JSON.toJavaObject(jsonArray.getJSONObject(j), SummaryDataPoJo.class);
                String attr = summary.getAttr();

                FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                if (Objects.isNull(fieldAttrEntity) && attr.indexOf(BusinessConstant.ADDRESS) > -1) {
                    fieldAttrEntity = explainMap.get(attr+StringConstant.POINT+BusinessConstant.ADDRESS);
                }
                if(Objects.isNull(fieldAttrEntity) || Objects.equals(0, fieldAttrEntity.getVisible())) {
                    continue;
                }
                List<Object> list = getSpecialDataList(fieldAttrEntity, data, paasFormDataEntityExt);
                summary.setValue(list);
                summary.setFieldType(fieldAttrEntity.getFieldType());
                summary.setAttrName(fieldAttrEntity.getAttrName());
                // 所在地区字段特殊处理
                if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.AREA.getType()) && CollectionsUtil.isNotEmpty(summary.getValue())) {
                    Object val = summary.getValue().get(0);
                    if (val instanceof Map) {
                        summary.setValue(Collections.singletonList(((Map)val).get("name")));
                    }
                }
                summaryList.add(summary);
            }
        } catch (Exception e) {
            LOG.error("PaasFormDataServiceImpl根据数据返回摘要，标签和标题信息", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return summaryList;
    }
    /**
     * Description: 单纯详情页底层解析(其他人提前解析了)
     * @param fieldAttrEntity
     * @param data
     * @param paasFormDataEntityExt
     * @author 刘阳
     * @date 2019/7/4 4:02 PM
     * @since v1.0
     */
    public static List<Object> getSpecialDataList(FieldAttrEntity fieldAttrEntity, JSONObject data, PaasFormDataEntityExt paasFormDataEntityExt) {
        Integer fieldType = fieldAttrEntity.getFieldType();
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        List<Object> list = new ArrayList<>();
        String attr = fieldAttrEntity.getAttr();
        // 百分比数字字段处理
        String saasAttr = fieldAttrEntity.getSaasAttr();
        boolean rateNumFlag = Objects.equals(ContractEnum.GROSS_PROFIT_RATE.getSaasAttr(), saasAttr)
                || Objects.equals(ContractEnum.CASH_PROFIT_RATE.getSaasAttr(), saasAttr)
                || Objects.equals(ContractEnum.PAY_PERCENT.getSaasAttr(), saasAttr)
                || Objects.equals(SalesOpportunityEnum.GROSS_PROFIT_RATE.getSaasAttr(), saasAttr)
                || Objects.equals(QuotationEnum.GROSS_PROFIT_RATE.getSaasAttr(), saasAttr)
                || Objects.equals(PurchaseEnum.RECEINE_PERCENT.getSaasAttr(), saasAttr);
        if (Objects.equals(fieldAttrEntity.getNumberType(), NumberTypeEnum.RATE.getCode())) {
            rateNumFlag = true;
        }
        Object attrValue= data.get(attr);
        switch (fieldTypeEnum) {
            case CHECKBOX_GROUP:
            case COMBO_CHECK:
                if (Objects.nonNull(attrValue)) {
                    if (attrValue instanceof String) {
                        list.add(attrValue);
                    } else if (attrValue instanceof ArrayList || attrValue instanceof JSONArray) {
                        boolean isItemPoJo = CollectionsUtil.isNotEmpty(data.getJSONArray(attr)) && !(data.getJSONArray(attr).get(0) instanceof String);;
                        if (isItemPoJo) {
                            list.addAll(((List<ItemPoJo>) attrValue).stream().map(ItemPoJo::getText).collect(Collectors.toList()));
                        } else {
                            list = ItemUtil.analysisComboReturnList(data, fieldAttrEntity);
                        }
                    } else {
                        List tempList = (List<Object>) attrValue;
                        list.addAll(tempList);
                    }

                }
                break;
            case COMBO:
            case RADIO_GROUP:
            case STAGE_THRUSTER:
                if (Objects.nonNull(attrValue)) {
                    Object type = null;
                    if (Objects.equals(ComboTypeEnum.CUSTOM.getType(), fieldAttrEntity.getComboType())) {
                        if (Objects.equals(fieldAttrEntity.getSaasAttr(), ProductEnum.UNIT.getSaasAttr()) && attrValue instanceof Number &&
                                Long.parseLong(attrValue.toString()) > ProductConstant.MAX_SINGLE_UNIT_VALUE) {
                            type = ItemUtil.getUnitItemList(fieldAttrEntity, data);
                        }else if (data.get(attr) instanceof ItemPoJo){
                            type = ((ItemPoJo) data.get(attr)).getText();
                        }else {
                            type = ItemUtil.getCustomItemList(fieldAttrEntity, data);
                        }
                        if (Objects.nonNull(type)) {
                            list.add(type);
                        }
                    } else {
                        if (attrValue instanceof ItemPoJo){
                            attrValue = ((ItemPoJo) attrValue).getValue();
                        }
                        for (ItemPoJo itemPoJo : fieldAttrEntity.getItems()) {
                            if (Objects.equals(attrValue.toString(), itemPoJo.getValue().toString())) {
                                attrValue = itemPoJo.getText();
                            }
                        }
                        if (!ItemUtil.isUUID(attrValue.toString())) {
                            list.add(attrValue);
                        }
                    }
                }
                break;
            case BIRTHDAY:
//                String linkedText = fieldAttrEntity.getLinkedText();
//                // 获取生日是公历还是阴历
//                Integer isLunarBirthdayShown = data.getInteger(linkedText);
                String birthday = data.getString(attr);
                list.add(birthday);
                break;
            case DATETIME:
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fieldAttrEntity.getDateType());
                Long dateTime = 0L;
                String dateStr = null;
                try {
                    boolean isLastConnectTimeAttr = (Objects.equals(fieldAttrEntity.getAttr(), CustomerManagementEnum.LAST_CONNECT_TIME.getAttr()) &&
                            Objects.equals(fieldAttrEntity.getSaasAttr(), CustomerManagementEnum.LAST_CONNECT_TIME.getSaasAttr()))
                            || (Objects.equals(fieldAttrEntity.getAttr(), ClueEnum.LAST_CONNECT_TIME.getAttr()) &&
                            Objects.equals(fieldAttrEntity.getSaasAttr(), ClueEnum.LAST_CONNECT_TIME.getSaasAttr()));
                    if(isLastConnectTimeAttr){
                        dateTime = data.getLong(attr) == null ? 0L : data.getLong(attr);
                        // 当最近跟进时间超过三个月，是2019-11-11 11:11,既可以getLong获取，也可以getString
                        if(String.valueOf(dateTime).contains("0000")){
                            dateTime = 0L;
                            dateStr = data.getString(attr);
                        }
                    } else {
                        dateTime = data.getLong(attr);
                    }

                } catch (Exception e) {
                    dateStr = data.getString(attr);
                }
                if (dateTime != null && dateTime != 0) {
                    list.add(DateTimeUtil.getStringEpochSecond(dateTime, simpleDateFormat));
                } else if(dateStr != null) {
                    list.add(dateStr);
                }
                break;
            case ADDRESS:
                if(attr.indexOf(StringConstant.POINT) > -1) {
                    attr = attr.replace(StringConstant.POINT+BusinessConstant.ADDRESS, "")
                            .replace(StringConstant.POINT + BusinessConstant.PROVINCE, "")
                            .replace(StringConstant.POINT + BusinessConstant.CITY, "")
                            .replace(StringConstant.POINT + BusinessConstant.DISTRICT, "");
                    String province = data.getOrDefault(attr + StringConstant.POINT + BusinessConstant.PROVINCE, "").toString();
                    String city = data.getOrDefault(attr + StringConstant.POINT + BusinessConstant.CITY, "").toString();
                    String district = data.getOrDefault(attr + StringConstant.POINT + BusinessConstant.DISTRICT, "").toString();
                    String address = "";
                    if (Objects.equals(fieldAttrEntity.getShowDetailAddress(), 1)) {
                        address = data.getOrDefault(attr + StringConstant.POINT + BusinessConstant.ADDRESS, "").toString();
                    }
                    list.add(province + city + district + address);

                } else {
                    JSONObject addressData = data.getJSONObject(attr);
                    if (Objects.nonNull(addressData)) {
                        String province = addressData.getString(BusinessConstant.PROVINCE);
                        String city = addressData.getString(BusinessConstant.CITY);
                        String district = addressData.getString(BusinessConstant.DISTRICT);
                        String address = "";
                        if (Objects.equals(fieldAttrEntity.getShowDetailAddress(), 1)) {
                            address = addressData.getString(BusinessConstant.ADDRESS);
                        }
                        list.add(province + city + district  + address);
                    }
                }
                break;
            case ADDTIME:
                SimpleDateFormat addTimeFormat = new SimpleDateFormat(fieldAttrEntity.getDateType());
                Long addTime = paasFormDataEntityExt.getAddTime();
                if (addTime != null && addTime != 0) {
                    list.add(DateTimeUtil.getStringEpochSecond(addTime, addTimeFormat));
                }
                break;
            case UPDATETIME:
                SimpleDateFormat updateTimeFormat = new SimpleDateFormat(fieldAttrEntity.getDateType());
                Long updateTime = paasFormDataEntityExt.getUpdateTime();
                if (updateTime != null && updateTime != 0) {
                    list.add(DateTimeUtil.getStringEpochSecond(updateTime, updateTimeFormat));
                }
                break;
            case USER:
            case DEPT:
            case CREATORID:
                if (Objects.nonNull(data.get(attr)) && StringUtil.isNotEmpty(data.getString(attr))) {
                    if (data.get(attr) instanceof ReturnUserAndDepartmentPojo) {
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = data.getJSONObject(attr).toJavaObject(ReturnUserAndDepartmentPojo.class);
                        list.add(returnUserAndDepartmentPojo.getName());
                    }else {
                        list.add(data.get(attr));
                    }
                }
                break;
            case USER_GROUP:
            case DEPT_GROUP:
            case OWNERID:
            case COUSERID:
                if (Objects.nonNull(data.get(attr)) && StringUtil.isNotEmpty(data.getString(attr))) {
                    if (data.get(attr) instanceof List) {
                        List<String> nameList = new ArrayList<>();
                        List<ReturnUserAndDepartmentPojo> returnUserAndDepartmentPojo = data.getJSONArray(attr).toJavaList(ReturnUserAndDepartmentPojo.class);
                        returnUserAndDepartmentPojo.forEach(item-> nameList.add(item.getName()));
                        list.add(StringUtils.join(nameList, "、"));
                    } else {
                        list.add(data.get(attr));
                    }
                }
                break;
            case SERIALNO:
                if (StringUtil.isNotEmpty(paasFormDataEntityExt.getSerialNo())) {
                    list.add(paasFormDataEntityExt.getSerialNo());
                }
                break;
            case STAR:
                Integer star = data.getInteger(attr);
                if (star == null || star == StarEnum.ZERO.getValue()) {
                    // 星级字段未操作则不显示
                    break;
                }
                list.add(StarEnum.getTextByValue(star));
                break;
            case LINK_BUSINESS_SINGLE:
            case LINK_BUSINESS_MULTI:
                if (Objects.nonNull(data.get(attr))) {
                    if (data.get(attr) instanceof List) {
                        JSONArray jsonArray = data.getJSONArray(attr);
                        if (jsonArray != null && !jsonArray.isEmpty()) {
                            StringBuilder name = new StringBuilder();
                            for (int i = 0; i < jsonArray.size(); i++) {
                                if (jsonArray.get(i) instanceof JSONObject) {
                                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                                    name.append(jsonObject.getString(StringConstant.SAAS_LINK_BUSINESS_NAME)).append(StringConstant.COMMA);
                                } else {
                                    if (fieldAttrEntity.getLinkedText() != null) {
                                        JSONArray linkArray = data.getJSONArray(fieldAttrEntity.getLinkedText());
                                        if (linkArray != null && !linkArray.isEmpty()) {
                                            for (int j = 0; j < linkArray.size(); j++) {
                                                String text = linkArray.getString(j);
                                                name.append(text).append(StringConstant.COMMA);
                                            }
                                        }
                                    }
                                    break;
                                }

                            }
                            // 去掉最后的","号
                            int length = name.length();
                            if (length > 0) {
                                String substringName = name.toString().substring(0, length - 1);
                                list.add(substringName);
                            }
                        }
                    } else {
                        if (fieldAttrEntity.getLinkedText() != null) {
                            if(Objects.nonNull(data.get(fieldAttrEntity.getLinkedText()))) {
                                list.add(data.get(fieldAttrEntity.getLinkedText()));
                            }
                        }
                    }
                }
                break;
            case TEXT_CHECK:
                if (attrValue instanceof String) {
                    if (Objects.nonNull(data.get(attr))) {
                        list.add(data.get(attr));
                    }
                } else {
                    if (Objects.nonNull(attrValue)) {
                        //checked,value格式
                        JSONObject jsonObject = JSONObject.parseObject(Objects.toString(attrValue, ""));
                        list.add(jsonObject.get("value"));
                    }
                }
                break;
            case DEPARTMENTID:
                if (Objects.nonNull(data.get(attr)) && StringUtil.isNotEmpty(data.getString(attr))) {
                    if (data.get(attr) instanceof ReturnUserAndDepartmentPojo) {
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = data.getJSONObject(attr).toJavaObject(ReturnUserAndDepartmentPojo.class);
                        list.add(returnUserAndDepartmentPojo.getName());
                    }else {
                        list.add(data.get(attr));
                    }
                }
                break;
            case NUM:
                if (Objects.nonNull(data.get(attr))) {
                    Object value = data.get(attr);
                    Object result = null;
                    Integer accuracy = fieldAttrEntity.getAccuracy();
                    Integer integerOnly = fieldAttrEntity.getIntegerOnly();
                    if (accuracy == null) {
                        accuracy = BasicConstant.DEFAULT_ACCURACY;
                    }
                    if(AmountFlagEnum.YES.getType().equals(fieldAttrEntity.getAmountFlag())){
                        String pattern = "##,##0.";
                        if (Objects.equals(accuracy, 0) || Objects.equals(integerOnly, 1)) {
                            pattern = "##,##0";
                        }
                        for (int i = 0; i < accuracy; i++) {
                            pattern = pattern + "0";
                        }
                        DecimalFormat df = new DecimalFormat(pattern);
                        if(value instanceof Integer || value instanceof Double ||
                                value instanceof BigDecimal || value instanceof Long || StringUtil.isDigital(value.toString())){
                            result =  df.format(Double.parseDouble(String.valueOf(value)));
                        }else {
                            result = value;
                        }
                    } else {
                        String pattern = "##0.";
                        if (Objects.equals(accuracy, 0) || Objects.equals(integerOnly, 1)) {
                            pattern = "##0";
                            accuracy = 0;
                        }
                        for (int i = 0; i < accuracy; i++) {
                            pattern = pattern + "0";
                        }
                        DecimalFormat df = new DecimalFormat(pattern);
                        if (Objects.equals(integerOnly, 1)) {
                            df.setRoundingMode(RoundingMode.DOWN);
                        }
                        if(value instanceof Integer || value instanceof Double ||
                                value instanceof BigDecimal || value instanceof Long || StringUtil.isDigital(value.toString())){
                            result =  df.format(Double.parseDouble(String.valueOf(value)));
                        }
                    }
                    if (Objects.nonNull(result)) {
                        list.add(result);
                    } else if (rateNumFlag) {
                        list.add(value);
                    }
                }
                break;
            case LABEL:
                JSONArray jsonArray = data.getJSONArray(attr);
                if(Objects.nonNull(jsonArray) && CollectionsUtil.isNotEmpty(jsonArray)){
                    for (int i = 0; i < jsonArray.size(); i++) {
                        Object object = jsonArray.get(i);
                        if (object instanceof LabelPojo || object instanceof JSONObject) {
                            JSONObject item = JSON.parseObject(JSON.toJSONString(object));
                            if (Objects.equals(item.getInteger("tabelType"),BasicConstant.ZERO)) {
                                list.add(item);
                            }
                        } else {
                            list.add(object);
                        }
                    }
                }
                break;
            case TEMPLATE_FIELD:
                JSONObject jsonObject = data.getJSONObject(attr);
                if(jsonObject!=null){
                    list.add(jsonObject.get(OnlineEditorConstant.BASE_CONTRACT_NAME));
                }
                break;
            default:
                if (Objects.nonNull(data.get(attr))) {
                    list.add(data.get(attr));
                }
                break;
        }
        return list;
    }

    public static List<Object> getDataList(FieldAttrEntity fieldAttrEntity, JSONObject data, PaasFormDataEntityExt paasFormDataEntityExt) {
        Integer fieldType = fieldAttrEntity.getFieldType();
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        List<Object> list = new ArrayList<>();
        String attr = fieldAttrEntity.getAttr();
        Object attrValue= data.get(attr);
        switch (fieldTypeEnum) {
            case CHECKBOX_GROUP:
            case COMBO_CHECK:
                if (Objects.nonNull(attrValue)) {
                    if (attrValue instanceof String) {
                        list.add(attrValue);
                    } else {
                        List tempList = (List<Object>) attrValue;
                        if (CollectionsUtil.isNotEmpty(tempList) && tempList.get(0) instanceof ItemPoJo){
                            list.addAll(((List<ItemPoJo>) tempList).stream().map(ItemPoJo::getText).collect(Collectors.toList()));
                        } else {
                            list.addAll(tempList);
                        }
                    }

                }
                break;
            case COMBO:
            case RADIO_GROUP:
            case STAGE_THRUSTER:
                if (Objects.nonNull(attrValue)) {
                    if (attrValue instanceof ItemPoJo){
                        ItemPoJo itemPoJo = (ItemPoJo) attrValue;
                        list.add(itemPoJo.getText());
                    } else {
                        list.add(ItemUtil.getComBoValue(fieldAttrEntity, data));
                    }
                }
                break;
            case BIRTHDAY:
//                String linkedText = fieldAttrEntity.getLinkedText();
//                // 获取生日是公历还是阴历
//                Integer isLunarBirthdayShown = data.getInteger(linkedText);
                String birthday = data.getString(attr);
                list.add(birthday);
                break;
            case DATETIME:
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fieldAttrEntity.getDateType());
                Long dateTime = 0L;
                String dateStr = null;
                try {
                   dateTime = data.getLong(attr);
                } catch (Exception e) {
                    dateStr = data.getString(attr);
                }
                if (dateTime != null && dateTime != 0) {
                    list.add(DateTimeUtil.getStringEpochSecond(dateTime, simpleDateFormat));
                } else if(dateStr != null) {
                    list.add(dateStr);
                }
                break;
            case ADDRESS:
            case LOCATION:
                if(attr.indexOf(StringConstant.POINT) > -1) {
                    attr = attr.replace(StringConstant.POINT+BusinessConstant.ADDRESS, "")
                            .replace(StringConstant.POINT + BusinessConstant.PROVINCE, "")
                            .replace(StringConstant.POINT + BusinessConstant.CITY, "")
                            .replace(StringConstant.POINT + BusinessConstant.DISTRICT, "");
                    String province = data.getOrDefault(attr + StringConstant.POINT + BusinessConstant.PROVINCE, "").toString();
                    String city = data.getOrDefault(attr + StringConstant.POINT + BusinessConstant.CITY, "").toString();
                    String district = data.getOrDefault(attr + StringConstant.POINT + BusinessConstant.DISTRICT, "").toString();
                    String address = "";
                    if (Objects.equals(fieldAttrEntity.getShowDetailAddress(), 1)) {
                        address = data.getOrDefault(attr + StringConstant.POINT + BusinessConstant.ADDRESS, "").toString();
                    }
                    list.add(province + city + district + address);

                } else {
                    Object addressData = data.get(attr);
                    if (Objects.nonNull(addressData)) {
                        if (addressData instanceof String) {
                            list.add(addressData);
                        } else if (addressData instanceof JSONObject) {
                            JSONObject jsonObject = (JSONObject) addressData;
                            String province = jsonObject.getString(BusinessConstant.PROVINCE);
                            String city = jsonObject.getString(BusinessConstant.CITY);
                            String district = jsonObject.getString(BusinessConstant.DISTRICT);
                            String address = "";
                            if (Objects.equals(fieldAttrEntity.getShowDetailAddress(), 1)) {
                                address = jsonObject.getString(BusinessConstant.ADDRESS);
                            }
                            list.add(province + city + district + address);
                        }
                    }
                }
                break;
            case ADDTIME:
                SimpleDateFormat addTimeFormat = new SimpleDateFormat(fieldAttrEntity.getDateType());
                Long addTime = paasFormDataEntityExt.getAddTime();
                if (addTime != null && addTime != 0) {
                    list.add(DateTimeUtil.getStringEpochSecond(addTime, addTimeFormat));
                }
                break;
            case UPDATETIME:
                SimpleDateFormat updateTimeFormat = new SimpleDateFormat(fieldAttrEntity.getDateType());
                Long updateTime = paasFormDataEntityExt.getUpdateTime();
                if (updateTime != null && updateTime != 0) {
                    list.add(DateTimeUtil.getStringEpochSecond(updateTime, updateTimeFormat));
                }
                break;
            case USER:
            case DEPT:
            case CREATORID:
                if (Objects.nonNull(data.get(attr)) && StringUtil.isNotEmpty(data.getString(attr))) {
                    if (data.get(attr) instanceof ReturnUserAndDepartmentPojo) {
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = JSON.parseObject(JSON.toJSONString(data.get(attr)), ReturnUserAndDepartmentPojo.class);
                        list.add(returnUserAndDepartmentPojo.getName());
                    }else {
                        list.add(data.get(attr));
                    }
                }
                break;
            case DEPARTMENTID:
                if (Objects.nonNull(data.get(attr)) && StringUtil.isNotEmpty(data.getString(attr)) && !Objects.equals(data.getString(attr), ZERO)) {
                    if (data.get(attr) instanceof ReturnUserAndDepartmentPojo) {
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = data.getJSONObject(attr).toJavaObject(ReturnUserAndDepartmentPojo.class);
                        list.add(returnUserAndDepartmentPojo.getName());
                    }else {
                        list.add(data.get(attr));
                    }
                }
                break;
            case USER_GROUP:
            case DEPT_GROUP:
            case OWNERID:
                if (Objects.nonNull(data.get(attr)) && StringUtil.isNotEmpty(data.getString(attr))) {
                    if (data.get(attr) instanceof List) {
                        List<ReturnUserAndDepartmentPojo> returnUserAndDepartmentPojo = JSON.parseArray(JSON.toJSONString(data.get(attr)), ReturnUserAndDepartmentPojo.class);
                        returnUserAndDepartmentPojo.forEach(item-> list.add(item.getName()));
                    } else {
                        list.add(data.get(attr));
                    }
                }
                break;
            case COUSERID:
                if (Objects.nonNull(data.get(attr)) && StringUtil.isNotEmpty(data.getString(attr))) {
                    if (data.get(attr) instanceof List) {
                        List<ReturnUserAndDepartmentPojo> returnUserAndDepartmentPojo = JSON.parseArray(JSON.toJSONString(data.get(attr)), ReturnUserAndDepartmentPojo.class);
                        returnUserAndDepartmentPojo.forEach(item-> list.add(item.getName()));
                    } else {
                        list.add(data.get(attr));
                    }
                }
                break;
            case SERIALNO:
                if (StringUtil.isNotEmpty(paasFormDataEntityExt.getSerialNo())) {
                    list.add(paasFormDataEntityExt.getSerialNo());
                }
                break;
            case STAR:
                Integer star = data.getInteger(attr);
                if (star == null || star == StarEnum.ZERO.getValue()) {
                    // 星级字段未操作则不显示
                    break;
                }
                list.add(StarEnum.getTextByValue(star));
                break;
            case LINK_BUSINESS_SINGLE:
            case LINK_BUSINESS_MULTI:
                if (Objects.nonNull(data.get(attr))) {
                    if (data.get(attr) instanceof List) {
                        JSONArray jsonArray = data.getJSONArray(attr);
                        if (jsonArray != null && !jsonArray.isEmpty()) {
                            StringBuilder name = new StringBuilder();
                            for (int i = 0; i < jsonArray.size(); i++) {
                                if (jsonArray.get(i) instanceof JSONObject) {
                                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                                    name.append(jsonObject.getString(StringConstant.SAAS_LINK_BUSINESS_NAME)).append(StringConstant.COMMA);
                                } else {
                                    if (fieldAttrEntity.getLinkedText() != null) {
                                        JSONArray linkArray = data.getJSONArray(fieldAttrEntity.getLinkedText());
                                        if (linkArray != null && !linkArray.isEmpty()) {
                                            for (int j = 0; j < linkArray.size(); j++) {
                                                String text = linkArray.getString(j);
                                                name.append(text).append(StringConstant.COMMA);
                                            }
                                        }
                                    }
                                    break;
                                }
                            }
                            // 去掉最后的","号
                            if (name.length() > 0) {
                                String substringName = name.toString().substring(0, name.length() - 1);
                                list.add(substringName);
                            } else {
                                list.add("");
                            }
                        }
                    } else {
                        if (fieldAttrEntity.getLinkedText() != null) {
                            list.add(data.get(fieldAttrEntity.getLinkedText()));
                        }
                    }
                }
                break;
            case LABEL:
                if (Objects.nonNull(data.get(attr)) && StringUtil.isNotEmpty(data.getString(attr))) {
                    if (data.get(attr) instanceof List) {
                        JSONArray jsonArray = data.getJSONArray(attr);
                        list.addAll(jsonArray);
                    } else {
                        list.add(data.get(attr));
                    }
                }
                break;
            case TEMPLATE_FIELD:
                if (Objects.nonNull(data.get(attr))) {
                    JSONObject jsonObject = data.getJSONObject(attr);
                    list.add(jsonObject.get(OnlineEditorConstant.BASE_CONTRACT_NAME));
                }
                break;
            case TEXT_CHECK:
            default:
                if (Objects.nonNull(data.get(attr))) {
                    list.add(data.get(attr));
                }
                break;
        }
        return list;
    }
    /**
     * 根据字段权限获取字段列表
     * @param explainList
     * @param fieldPermissionEntityList
     * @return
     * @throws XbbException
     */
    public static List<FieldAttrEntity> parseExplainListByFieldPermission(List<FieldAttrEntity> explainList, List<FieldPermissionEntityExt> fieldPermissionEntityList, boolean isStartNode, Integer businessType, UserVO loginUser) throws XbbException{

        Map<String, FieldPermissionEntityExt> fieldPermissionMap = new HashMap<>(fieldPermissionEntityList.size());
        fieldPermissionEntityList.forEach((item)->{
            if(StringUtil.isNotEmpty(item.getSubAttr())){
                fieldPermissionMap.put(item.getAttr()+"."+item.getSubAttr(), item);
            }else{
                fieldPermissionMap.put(item.getAttr(), item);
            }
        });
       return parseExplainListByFieldPermission(explainList, fieldPermissionMap, isStartNode, businessType, false, loginUser);
    }

    /**
     *
     *
     * @param explainList
     * @param fieldPermissionMap
     * @param isStartNode
     * @param businessType
     * @param workflowTag 代表是否是工作流业务 true:是；false：否
     * @return
     * @throws XbbException
     */
    public static List<FieldAttrEntity> parseExplainListByFieldPermission(List<FieldAttrEntity> explainList, Map<String, FieldPermissionEntityExt> fieldPermissionMap, boolean isStartNode, Integer businessType,
                                                                          boolean workflowTag, UserVO loginUser) throws XbbException {
        List<FieldAttrEntity> headList = new ArrayList<>();
        //需要处理的几个工作流放出关联产品字段的业务
        List<Integer> workflowProductBusList = BusinessProductCompareEnum.getProductHandleBusList();
        boolean shouldHanldTag = workflowProductBusList.contains(businessType) && workflowTag;
        try {
            for (FieldAttrEntity item : explainList) {
                // 小鲍说分割线和描述文本必定显示
                if (Objects.equals(item.getFieldType(), FieldTypeEnum.SEPARATOR.getType()) || Objects.equals(item.getFieldType(), FieldTypeEnum.MEMO.getType())) {
                    headList.add(item);
                    continue;
                }
                if (Objects.equals(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), businessType) && Objects.equals(item.getAttr(), PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr())) {
                    item.setEditable(BasicConstant.ZERO);
                }
                if (Objects.equals(XbbRefTypeEnum.PAY_SHEET.getCode(), businessType) && Objects.equals(item.getAttr(), PaySheetEnum.WRITE_OFF_AMOUNT.getAttr())) {
                    item.setEditable(BasicConstant.ZERO);
                }
                if(fieldPermissionMap.containsKey(item.getAttr())){
                    // 开始节点的可见即可编辑
                    if (Objects.equals(fieldPermissionMap.get(item.getAttr()).getVisible(), 1) && isStartNode) {
                        if (Objects.equals(businessType, XbbRefTypeEnum.QUOTATION.getCode()) && (Objects.equals(item.getAttr(), QuotationEnum.QUOTATION_NO.getAttr()) || Objects.equals(item.getAttr(), QuotationEnum.PRODUCT_TOTAL.getAttr()))) {
                            item.setEditable(0);
                        } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) && Objects.equals(item.getAttr(), ContractEnum.PRODUCT_TOTAL.getAttr())) {
                            item.setEditable(0);
                        } else if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode()) && Objects.equals(item.getAttr(), PurchaseEnum.PRODUCT_TOTAL.getAttr())) {
                            item.setEditable(0);
                        }  else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode()) && Objects.equals(item.getAttr(), RefundEnum.REFUND_AMOUNT.getAttr())) {
                            item.setEditable(0);
                        } else {
                            item.setEditable(1);
                        }
                    } else if(Objects.equals(fieldPermissionMap.get(item.getAttr()).getEditable(), 1)){
                        if(!Objects.equals(item.getAttr(), InvoiceEnum.INVOICE_DATE.getAttr())){
                            item.setEditable(1);
                        }
                        if (Objects.equals(XbbRefTypeEnum.PAY_SHEET.getCode(), businessType) && Objects.equals(item.getAttr(), PaySheetEnum.WRITE_OFF_AMOUNT.getAttr())) {
                            item.setEditable(BasicConstant.ZERO);
                        }else if (Objects.equals(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), businessType) && Objects.equals(item.getAttr(), PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr())) {
                            item.setEditable(BasicConstant.ZERO);
                        }else {
                            item.setEditable(1);
                        }
                        /*if (Objects.equals(item.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType())) {
                            JSONArray jsonArray = item.getSubForm().getItems();
                            List<FieldAttrEntity> subExplainList = JSON.parseArray(JSON.toJSONString(jsonArray), FieldAttrEntity.class);
                            subExplainList.forEach(subItem -> subItem.setEditable(1));
                            item.getSubForm().setItems(JSON.parseArray(JSON.toJSONString(subExplainList)));
                        }*/
                    } else {
                        item.setEditable(0);
                        if ((Objects.equals(item.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType()) && !shouldHanldTag) ||
                                Objects.equals(item.getFieldType(), FieldTypeEnum.SINGLE_SUB_FORM.getType())) {
                            List<? extends FieldAttrEntity> jsonArray = item.getSubForm().getItems();
                            jsonArray.forEach(subItem -> {
                                subItem.setEditable(0);
                                // 字段回收站逻辑特殊处理
                                if (Objects.equals(subItem.getIsOpen(), 2)) {
                                    subItem.setVisible(0);
                                }
                            });
                            item.getSubForm().setItems(jsonArray);
                        }
                    }
                    if(Objects.equals(fieldPermissionMap.get(item.getAttr()).getVisible(), 1)){
                        if(FieldTypeEnum.SUB_FORM.getType().equals(item.getFieldType())
                                || FieldTypeEnum.CONTACT_NUMBER.getType().equals(item.getFieldType())
                                || (Objects.equals(item.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType()) && shouldHanldTag)){
                            List<? extends FieldAttrEntity> subExplainList = item.getSubForm().getItems();
                            List<FieldAttrEntity> fieldList = new ArrayList<>(subExplainList.size());
                            boolean trueHandleTag = Objects.equals(item.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType()) && shouldHanldTag;
                            //需要处理的工作流业务CRM模块的关联产品字段放出来需求，上线的时候fieldPermissionMap可能为空，所以这边需要做一下兼容处理
                            if (trueHandleTag) {
                                handleDefaultFieldPermissionMap(businessType, fieldPermissionMap, item);
                            }
                            subExplainList.forEach((subItem)->{
                                String key = item.getAttr()+"."+subItem.getAttr();
                                if(fieldPermissionMap.containsKey(key)){
                                    if(Objects.equals(fieldPermissionMap.get(key).getEditable(), 1)
                                            || (Objects.equals(fieldPermissionMap.get(key).getVisible(), 1) && isStartNode && !trueHandleTag)){
                                        subItem.setEditable(1);
                                    }else{
                                        subItem.setEditable(0);
                                    }
                                    if(Objects.equals(fieldPermissionMap.get(key).getVisible(), 1)){
                                        subItem.setVisible(1);
                                    } else if (Objects.equals(fieldPermissionMap.get(key).getVisible(), 0)) {
                                        subItem.setVisible(0);
                                    }
                                    // 字段回收站逻辑特殊处理
                                    if (Objects.equals(subItem.getIsOpen(), 2)) {
                                        subItem.setVisible(0);
                                    }
                                    fieldList.add(subItem);
                                }
                            });
                            item.getSubForm().setItems(fieldList);
                        }
                        // 字段回收站逻辑特殊处理
                        if (!Objects.equals(item.getIsOpen(), 2)) {
                            item.setVisible(1);
                        } else {
                            item.setVisible(0);
                        }
                        //启用了电话掩码的电话字段在审批处不可见 该不可见权限大于 表单设计页和流程设计处权限
                        if (ExplainUtil.isOpenTelephoneMask(item, loginUser)) {
                            item.setVisible(0);
                        }
                        headList.add(item);
                    } else {
                        item.setVisible(0);
                        headList.add(item);
                    }
                } else {
                    if (Objects.equals(item.getIsRedundant(), 0)) {
                        // 处理团队成员放出 回款单、付款单、应收款、付款计划、联系人、供应商联系人 负责人和协同人 字段后老数据
                        if (Objects.equals(item.getAttr(), "ownerId") || Objects.equals(item.getAttr(), "coUserId")) {
                            item.setVisible(BasicConstant.ONE);
                            item.setEditable(BasicConstant.ZERO);
                        }
                        headList.add(item);
                    }
                }
            }
        }catch (Exception e) {
            LOG.error("获取字段权限出错：", e);
        }
        return headList;
    }

    /**
     * 处理审批中默认的节点的表单字段权限
     *
     * @param businessType
     * @param fieldPermissionMap
     * @param fieldPermissionMap
     */
    public static void handleDefaultFieldPermissionMap(Integer businessType, Map<String, FieldPermissionEntityExt> fieldPermissionMap,
                                                        FieldAttrEntity productAttr) throws XbbException{
        List<String> unEditableFieldList = BusinessProductCompareEnum.getAllUnEditableFieldList(businessType);
        String prefix = productAttr.getAttr();
        List<? extends FieldAttrEntity> itemList = productAttr.getSubForm().getItems();
        Integer productEditable = productAttr.getEditable();
        Integer productVisible = productAttr.getVisible();
        for (FieldAttrEntity fieldAttrEntity : itemList) {
            String key = fieldAttrEntity.getAttr();
            String finalKey = prefix + "." + key;
            if (!fieldPermissionMap.containsKey(finalKey)) {
                Integer editable = productEditable;
                if (unEditableFieldList.contains(key)) {
                    editable = BasicConstant.ZERO;
                }
                fieldPermissionMap.put(finalKey, new FieldPermissionEntityExt(key, fieldAttrEntity.getFieldType(), editable, productVisible, BasicConstant.ZERO));
            }
        }
    }

    /**
     * 获取除子表单和添加联系人的字段列表
     * @param handlerExplainVO
     * @return
     */
    public static HandlerExplainVO getFieldListNoIncludeSubForm(HandlerExplainVO handlerExplainVO) throws XbbException {
        HandlerExplainVO resultHandlerExplainVO = new HandlerExplainVO();
        try {
            List<FieldAttrEntity> resultFieldList = new ArrayList<>();
            List<FieldAttrEntity> explainList = handlerExplainVO.getHeadList();
            Integer businessType = handlerExplainVO.getBusinessType();
            Integer saasMark = handlerExplainVO.getSaasMark();
            for (FieldAttrEntity item : explainList) {
                //评分过滤掉
                if(Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),businessType) && Objects.equals(CustomerManagementEnum.SCORE.getAttr(),item.getAttr())){
                    continue;
                }
                if(Objects.equals(XbbRefTypeEnum.CLUE.getCode(),businessType) && Objects.equals(ClueEnum.SCORE.getAttr(),item.getAttr())){
                    continue;
                }
                // 采购合同时，并且字段为付款计划不加基本信息中
                if (PurchaseEnum.ADD_PAYPLAN.getAttr().equals(item.getAttr())
                        && Objects.equals(XbbRefTypeEnum.PURCHASE.getCode(), businessType)
                        && Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
                    continue;
                }
                if (!FieldTypeEnum.SUB_FORM.getType().equals(item.getFieldType())&&
                        !FieldTypeEnum.SINGLE_SUB_FORM.getType().equals(item.getFieldType())
                    && !FieldTypeEnum.SELECT_PRODUCT.getType().equals(item.getFieldType())
                    && !FieldTypeEnum.SELECT_SERVICE.getType().equals(item.getFieldType())
                        && !FieldTypeEnum.LINK_FORM.getType().equals(item.getFieldType())) {
                    resultFieldList.add(item);
                }
            }
            resultHandlerExplainVO.setHeadList(resultFieldList);
        } catch (Exception e) {
            LOG.error("ExplainUtil.getFieldListNoIncludeSubForm 获取除子表单和添加联系人的字段列表出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return resultHandlerExplainVO;
    }

    /**
     * 获取除子表单和添加联系人的字段列表
     * @param handlerExplainVO
     * @return
     */
    public static HandlerExplainVO getFieldListWorkReport(HandlerExplainVO handlerExplainVO) throws XbbException {
        HandlerExplainVO resultHandlerExplainVO = new HandlerExplainVO();
        try {
            List<FieldAttrEntity> resultFieldList = new ArrayList<>();
            List<FieldAttrEntity> explainList = handlerExplainVO.getHeadList();
            for (FieldAttrEntity item : explainList) {
                Boolean result = !FieldTypeEnum.SUB_FORM.getType().equals(item.getFieldType())
                        && !FieldTypeEnum.SELECT_PRODUCT.getType().equals(item.getFieldType());
                if (result || WorkReportDailyEnum.NEXT_PLAN.getAttr().equals(item.getAttr())
                        || WorkReportMonthlyEnum.NEXT_PLAN.getAttr().equals(item.getAttr())
                        || WorkReportWeeklyEnum.NEXT_PLAN.getAttr().equals(item.getAttr())) {
                    resultFieldList.add(item);
                }
            }
            resultHandlerExplainVO.setHeadList(resultFieldList);
        } catch (Exception e) {
            LOG.error("ExplainUtil.getFieldListWorkReport 获取除子表单和添加联系人的字段列表出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return resultHandlerExplainVO;
    }

    /**
     * 获取子表单的字段列表
     * @param handlerExplainVO
     * @return
     */
    public static List<DetailTabPojo> getFieldListIncludeSubForm(HandlerExplainVO handlerExplainVO, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        List<DetailTabPojo> detailTabList = new ArrayList<>();
        try {
            List<FieldAttrEntity> explainList = handlerExplainVO.getHeadList();
            for (FieldAttrEntity item : explainList) {
                DetailTabPojo detailTabPojo = new DetailTabPojo();
                detailTabPojo.setAttr(item.getAttr());
                detailTabPojo.setName(item.getAttrName());
                if (FieldTypeEnum.SUB_FORM.getType().equals(item.getFieldType()) || FieldTypeEnum.SELECT_PRODUCT.getType().equals(item.getFieldType())) {
                    if (isFieldNeedHide(item, handlerExplainDTO)) {
                        continue;
                    }
                    detailTabPojo.setKey(FieldTypeEnum.SUB_FORM.getEsalias());
                    if (FieldTypeEnum.SELECT_PRODUCT.getType().equals(item.getFieldType())) {
                        detailTabPojo.setKey(StringConstant.TABLE_FORM);
                    }
                    List<? extends FieldAttrEntity> subExplainList = item.getSubForm().getItems();
                    // 过滤掉不可见字段
                    subExplainList.removeIf(subItem -> Objects.equals(0, subItem.getVisible()));
                    item.getSubForm().setItems(subExplainList);
                    detailTabPojo.setFieldAttrEntity(item);
                    detailTabList.add(detailTabPojo);
                }
            }
        } catch (Exception e) {
            LOG.error("ExplainUtil.getFieldListIncludeSubForm获取除子表单和添加联系人的字段列表出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return detailTabList;
    }
    /**
     * 工作报告获取子表单但是不包括下周计划、下月计划、明日计划的字段列表
     * @param handlerExplainVO
     * @return
     */
    public static List<DetailTabPojo> getSubFormToTabWorkReport(HandlerExplainVO handlerExplainVO, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        List<DetailTabPojo> detailTabList = new ArrayList<>();
        try {
            List<FieldAttrEntity> explainList = handlerExplainVO.getHeadList();

            for (FieldAttrEntity item : explainList) {
                DetailTabPojo detailTabPojo = new DetailTabPojo();
                detailTabPojo.setAttr(item.getAttr());
                detailTabPojo.setName(item.getAttrName());
                if (FieldTypeEnum.SUB_FORM.getType().equals(item.getFieldType())
                    && !WorkReportDailyEnum.NEXT_PLAN.getAttr().equals(item.getAttr())
                        && !WorkReportMonthlyEnum.NEXT_PLAN.getAttr().equals(item.getAttr())
                        && !WorkReportWeeklyEnum.NEXT_PLAN.getAttr().equals(item.getAttr()) ) {
                    if (isFieldNeedHide(item, handlerExplainDTO)) {
                        continue;
                    }
                    detailTabPojo.setKey(FieldTypeEnum.SUB_FORM.getEsalias());
                    if (FieldTypeEnum.SELECT_PRODUCT.getType().equals(item.getFieldType())) {
                        detailTabPojo.setKey(StringConstant.TABLE_FORM);
                    }
                    List<? extends FieldAttrEntity> subExplainList = item.getSubForm().getItems();
                    // 过滤掉不可见字段
                    // 子表单里没有高级可见，所以不需要了
                    subExplainList.removeIf(subItem -> Objects.equals(0, subItem.getVisible()));
                    item.getSubForm().setItems(subExplainList);
                    detailTabPojo.setFieldAttrEntity(item);
                    detailTabList.add(detailTabPojo);
                }
            }
        } catch (Exception e) {
            LOG.error("获取除子表单和添加联系人的字段列表出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return detailTabList;
    }

    /**
     * 获取需要更新的数据
     * 注：该方法会更新updateTime为当前时间
     * @param id 数据id
     * @param dataJSONObject 要更新字段的容器
     * @param corpid 公司id
     * @return
     */
    public static UpdateDataEntity getUpdateData(Long id, JSONObject dataJSONObject, String corpid) {
        long now = DateUtil.getInt();
        return getUpdateData(id, dataJSONObject, corpid, now);
    }

    /**
     * 获取需要更新的数据
     * 注：该方法可根据需求确定是否更新updateTime
     * @param id 数据id
     * @param dataJSONObject 要更新字段的容器
     * @param corpid 公司id
     * @param updateTime 如果不想更新updateTime，则传null或传原始数据的updateTime即可（最好传原数据的updateTime，防止mapper内未判断updateTime为空造成错误，如果传null，需要确保对应业务的mapper内判断updateTime是否为空）
     * @return com.xbongbong.pro.domain.entity.UpdateDataEntity
     * @author 吴峰
     * @since v1.0
     * @version v1.0
     * @update 2019/12/31 by zcp 增加updateTime参数，用于处理不更新updateTime的情况
     */
    public static UpdateDataEntity getUpdateData(Long id, JSONObject dataJSONObject, String corpid, Long updateTime) {
        UpdateDataEntity updateDataEntity = new UpdateDataEntity();
        updateDataEntity.setId(id);
        List<UpdateDataValueEntity> data = new ArrayList<>();
        Iterator iterable = dataJSONObject.keySet().iterator();
        while (iterable.hasNext()) {
            String key = iterable.next().toString();
            UpdateDataValueEntity updateDataValueEntity = new UpdateDataValueEntity();
            updateDataValueEntity.setKey(key);
            updateDataValueEntity.setEsKey(key);
            updateDataValueEntity.setValue(dataJSONObject.get(key));
            if (Objects.equals(FieldTypeEnum.DEPARTMENTID.getAlias(), key)) {
                // 所属部门
                if (Objects.nonNull(dataJSONObject.get(key)) && (dataJSONObject.get(key) instanceof Map || dataJSONObject.get(key) instanceof ReturnUserAndDepartmentPojo)) {
                    JSONObject linkData = dataJSONObject.getJSONObject(key);
                    if (Objects.nonNull(linkData)) {
                        updateDataEntity.setDepartmentId(linkData.getLong(StringConstant.SAAS_LINK_BUSINESS_ID));
                    }
                }
                if (Objects.isNull(dataJSONObject.get(key))) {
                    updateDataEntity.setDepartmentId(0L);
                }
                continue;
            }
            if (key.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                // TODO 子表单不参加更新
                continue;
            } else if (dataJSONObject.get(key) instanceof ArrayList || dataJSONObject.get(key) instanceof JSONArray || dataJSONObject.get(key) instanceof HashSet || dataJSONObject.get(key) instanceof Object[] || dataJSONObject.get(key) instanceof List) {
                // 更新多选和复选
                updateDataValueEntity.setDataType("JSON_ARRAY");
                JSONArray array = new JSONArray();
                if (Objects.nonNull(dataJSONObject.get(key))) {
                    array = dataJSONObject.getJSONArray(key);
                }
                updateDataValueEntity.setValue(array);
            } else if (dataJSONObject.get(key) instanceof JSONObject || dataJSONObject.get(key) instanceof HashMap) {
                // 更新地址和定位
                updateDataValueEntity.setDataType(DataTypeEnum.JSON_OBJECT.getDataType());
                JSONObject jsonObject = dataJSONObject.getJSONObject(key);
                if (key.contains(BusinessConstant.ADDRESS) && jsonObject.get(BusinessConstant.LOCATION) instanceof String) {
                    jsonObject.remove(BusinessConstant.LOCATION);
                }
                updateDataValueEntity.setValue(jsonObject);
            }
            data.add(updateDataValueEntity);
        }
        updateDataEntity.setData(data);
        updateDataEntity.setCorpid(corpid);
        //如果不想更新updateTime，则传null或传原始数据的updateTime即可（最好传原数据的updateTime，防止mapper内未判断updateTime为空造成错误）
        if (Objects.nonNull(updateTime)) {
            updateDataEntity.setUpdateTime(updateTime);
        }
        return updateDataEntity;
    }

    /**
     * 获取saas可编辑字段
     * @param xbbRefTypeEnum 业务类型
     * @return 返回可编辑字段
     * @throws XbbException
     */
    public static Set<String> getSaasEditAttr(XbbRefTypeEnum xbbRefTypeEnum) throws XbbException {
        Set<String> saasEditAttrSet = new HashSet<>();
        try {
            String alias = xbbRefTypeEnum.getAlias();
            Class clazz = SaasEditAttrConstant.class;
            Object constant = getConst(alias.toUpperCase(), clazz);
            if (Objects.nonNull(constant)) {
                Object object = getConst(alias.toUpperCase(), clazz);
                if (Objects.isNull(object)) {
                    return saasEditAttrSet;
                }
                String[] saasEditAttrArray = (String[]) object;
                for(String saasEditAttr: saasEditAttrArray) {
                    saasEditAttrSet.add(saasEditAttr);
                }
            }
        } catch (Exception e) {
            LOG.error("saasUpdateHelp.getSaasEditAttr 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return saasEditAttrSet;
    }

    /**
     * 根据字段获取对应的值
     * @param field 字段
     * @param clazz 类
     * @return 返回字段对应的值
     * @throws XbbException
     */
    public static Object getConst(String field, Class clazz) throws XbbException{
        try {
            return clazz.getField(field).get(null);
        } catch (NoSuchFieldException e) {
            return null;
        } catch (Exception e) {
            LOG.error("saasUpdateHelp.getConst 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 产品成本需要隐藏
     * @author 吴峰
     * @date 2019/4/8 20:01
     * @param fieldAttrEntity 产品字段容器
     * @param handlerExplainDTO 前端参数
     * @return java.lang.Boolean ture:隐藏；false：不隐藏
     * @throws XbbException 业务异常
     */
    public static Boolean isFieldNeedHide(FieldAttrEntity fieldAttrEntity, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        if(Objects.equals(fieldAttrEntity.getVisible(), 1)) {
            return invisibleOfScope(fieldAttrEntity, handlerExplainDTO);
        } else {
            return true;
        }
    }

    /**
     * 判断高级规则是否可见
     * @param fieldAttrEntity
     * @param handlerExplainDTO
     * @return java.lang.Boolean ture:隐藏；false：不隐藏
     * @throws XbbException
     */
    public static Boolean invisibleOfScope(FieldAttrEntity fieldAttrEntity, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        if (Objects.isNull(fieldAttrEntity)) {
            return true;
        }
        Integer visibleScopeEnable = fieldAttrEntity.getVisibleScopeEnable();
        // 高级可见规则回显用户名称
        VisibleRulePoJo visibleRulePoJo = fieldAttrEntity.getVisibleScopeRule();
        if (Objects.equals(1, visibleScopeEnable) && Objects.nonNull(visibleRulePoJo)) {
            Integer type = visibleRulePoJo.getType();
            VisibleTypeEnum visibleTypeEnum = VisibleTypeEnum.getByType(type);
            switch (visibleTypeEnum) {
                case NOT_SHOW_ANYONE:
                    // 不给谁看
                    return ExplainUtil.notShowAnyOne(visibleRulePoJo, handlerExplainDTO);
                case SOME_PEOPLE_CAN_SEE:
                    // 部分人可见；
                    return ExplainUtil.fieldCanSee(visibleRulePoJo, handlerExplainDTO);
                default:
                    return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 判断高级规则是否可新增，可删除
     * @param fieldAttrEntity
     * @param handlerExplainDTO
     * @return java.lang.Boolean ture:隐藏；false：不隐藏
     * @throws XbbException
     */
    public static Boolean advancedOperationHavePermission(FieldAttrEntity fieldAttrEntity, HandlerExplainDTO handlerExplainDTO, Integer operate) throws XbbException {
        Integer scopeEnable = 1;
        Integer enable = 1;
        VisibleRulePoJo visibleRulePoJo = null;
        if (Objects.equals(operate, FieldAdvanceOperationEnum.ADD.getOperation())) {
            scopeEnable = fieldAttrEntity.getAddAdvanceEnable();
            visibleRulePoJo = fieldAttrEntity.getAddRule();
            enable = fieldAttrEntity.getAdd();
        } else if (Objects.equals(operate, FieldAdvanceOperationEnum.DEL.getOperation())) {
            scopeEnable = fieldAttrEntity.getRemoveAdvanceEnable();
            visibleRulePoJo = fieldAttrEntity.getRemoveRule();
            enable = fieldAttrEntity.getRemove();
        }
        // 是否开启
        if (Objects.equals(enable , 1)) {
            if (Objects.equals(scopeEnable, 1) && Objects.nonNull(visibleRulePoJo)) {
                if (Objects.equals(visibleRulePoJo.getType(), VisibleTypeEnum.SOME_PEOPLE_CAN_SEE.getType())) {
                    return ExplainUtil.fieldCanOperation(visibleRulePoJo, handlerExplainDTO);
                }
                if (Objects.equals(visibleRulePoJo.getType(), VisibleTypeEnum.NOT_SHOW_ANYONE.getType())) {
                    return ExplainUtil.fieldNotCanOperation(visibleRulePoJo, handlerExplainDTO);
                }
            } else {
                return true;
            }
        } else if (Objects.isNull(enable)){
            return true;
        } else {
            return false;
        }
        return true;
    }

    /**
     * 判断一个list时否包含另一个List的值
     *
     * @param addMainUserList
     * @param delCoUserList
     * @return
     */
    public static boolean judgeListContainsAnotherListOneValue(List<String> addMainUserList, List<String> delCoUserList) {

        if( CollectionUtils.isEmpty(addMainUserList) ||  CollectionUtils.isEmpty(delCoUserList)){
            return false;
        }
        if (addMainUserList.size() >= delCoUserList.size()) {
            for (String user : delCoUserList) {
                if (addMainUserList.contains(user)) {
                    return true;
                }
            }
        }
        if (addMainUserList.size() < delCoUserList.size()) {
            for (String user : addMainUserList) {
                if (delCoUserList.contains(user)) {
                    return true;
                }
            }
        }
        return false;
    }

    private static Boolean fieldCanOperation(VisibleRulePoJo visibleRulePoJo, HandlerExplainDTO handlerExplainDTO) {
        // 可操作
        List<Integer> relative = visibleRulePoJo.getRelative();
        List<VisibleRuleVO> department = visibleRulePoJo.getDep();
        List<Integer> role = visibleRulePoJo.getRole();
        List<String> userIds = visibleRulePoJo.getUser();
        UserVO userVO = handlerExplainDTO.getLoginUser();
        String userId = handlerExplainDTO.getUserId();

        if (Objects.nonNull(relative) && !relative.isEmpty()) {
            Set<Integer> relativeSet = new HashSet<>(relative);
            // 创建者
            if (relativeSet.contains(RelatedPersonnelEnum.CREATOR.getType())  && Objects.nonNull(handlerExplainDTO.getCreatorId())
                    && Objects.equals(userId, handlerExplainDTO.getCreatorId())) {
                return true;
            }
            // 负责人
            if (relativeSet.contains(RelatedPersonnelEnum.OWNER.getType()) && Objects.nonNull(handlerExplainDTO.getOwnerId())
                    && handlerExplainDTO.getOwnerId().contains(userId)) {
                return true;
            }
            // 负责人主管
            if (relativeSet.contains(RelatedPersonnelEnum.OWNER_SUP.getType()) && Objects.nonNull(handlerExplainDTO.getSubIdList())
                    && ExplainUtil.judgeListContainsAnotherListOneValue(handlerExplainDTO.getSubIdList(), handlerExplainDTO.getOwnerId())) {
                return true;
            }
            // 协同人
            if (relativeSet.contains(RelatedPersonnelEnum.CO_USER.getType()) && Objects.nonNull(handlerExplainDTO.getCoUserId())
                    && handlerExplainDTO.getCoUserId().contains(userId)) {
                return true;
            }
        }
        if (Objects.nonNull(department) && !department.isEmpty()) {
            Set<Object> departmentIdSet = new HashSet<>();
            department.forEach(item->{
                departmentIdSet.add(Long.parseLong(item.getId().toString()));
            });
            Set<DepartmentVO> departmentSet = userVO.getDepSet();
            List<DepartmentVO> departmentVOList = new ArrayList<>(departmentSet);
            for (DepartmentVO item : departmentVOList) {
                if (departmentIdSet.contains(item.getId())) {
                    return true;
                }
            }
        }
        if(checkRole(role, userVO)){
            return true;
        }
        if(Objects.nonNull(userIds) && userIds.contains(userId)) {
            return true;
        }
        return false;
    }

    private static Boolean fieldNotCanOperation(VisibleRulePoJo visibleRulePoJo, HandlerExplainDTO handlerExplainDTO) {
        // 可操作
        List<Integer> relative = visibleRulePoJo.getRelative();
        List<VisibleRuleVO> department = visibleRulePoJo.getDep();
        List<Integer> role = visibleRulePoJo.getRole();
        List<String> userIds = visibleRulePoJo.getUser();
        UserVO userVO = handlerExplainDTO.getLoginUser();
        String userId = handlerExplainDTO.getUserId();

        if (Objects.nonNull(relative) && !relative.isEmpty()) {
            Set<Integer> relativeSet = new HashSet<>(relative);
            // 创建者
            if (relativeSet.contains(RelatedPersonnelEnum.CREATOR.getType())  && Objects.nonNull(handlerExplainDTO.getCreatorId())
                    && Objects.equals(userId, handlerExplainDTO.getCreatorId())) {
                return false;
            }
            // 负责人
            if (relativeSet.contains(RelatedPersonnelEnum.OWNER.getType()) && Objects.nonNull(handlerExplainDTO.getOwnerId())
                    && handlerExplainDTO.getOwnerId().contains(userId)) {
                return false;
            }
            // 负责人主管
            if (relativeSet.contains(RelatedPersonnelEnum.OWNER_SUP.getType()) && Objects.nonNull(handlerExplainDTO.getSubIdList())
                    && handlerExplainDTO.getSubIdList().contains(userId)) {
                return false;
            }
            // 协同人
            if (relativeSet.contains(RelatedPersonnelEnum.CO_USER.getType()) && Objects.nonNull(handlerExplainDTO.getCoUserId())
                    && handlerExplainDTO.getCoUserId().contains(userId)) {
                return false;
            }
        }
        if (Objects.nonNull(department) && !department.isEmpty()) {
            Set<Object> departmentIdSet = new HashSet<>();
            department.forEach(item->{
                departmentIdSet.add(item.getId());
            });
            Set<DepartmentVO> departmentSet = userVO.getDepSet();
            List<DepartmentVO> departmentVOList = new ArrayList<>(departmentSet);
            for (DepartmentVO item : departmentVOList) {
                if (departmentIdSet.contains(item.getId())) {
                    return false;
                }
            }
        }
        if (Objects.nonNull(role) && !role.isEmpty()) {
            Set<Integer> roleIdSet = new HashSet<>(role);
            Set<RoleSimpleVO> roleSet = userVO.getRoleSet();
            List<RoleSimpleVO> roleVOList = new ArrayList<>(roleSet);
            for (RoleSimpleVO roleVO : roleVOList) {
                if (roleIdSet.contains(roleVO.getId())) {
                    return false;
                }
            }
        }
        if(Objects.nonNull(userIds) && userIds.contains(userId)) {
            return false;
        }
        return true;
    }

    /**
     * 判断是否可编辑
     * @param fieldAttrEntity
     * @param handlerExplainDTO
     * @return java.lang.Boolean ture 可编辑  false 不可编辑
     * @throws XbbException
     * @author xingxing.xiao
     */
    public static Boolean isEditableOfScope(FieldAttrEntity fieldAttrEntity, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        // 是否启用可编辑
        if (Objects.equals(fieldAttrEntity.getEditable(), 1)) {

            // 判断高级编辑规则 （复用老哥的‘是否可见’的判断逻辑，做了少许改变）
            Integer editableAdvanceEnable = fieldAttrEntity.getEditableAdvanceEnable();
            VisibleRulePoJo visibleRulePoJo = fieldAttrEntity.getEditableRule();
            if (Objects.equals(editableAdvanceEnable, 1) && Objects.nonNull(visibleRulePoJo)) {
                Integer type = visibleRulePoJo.getType();
                VisibleTypeEnum visibleTypeEnum = VisibleTypeEnum.getByType(type);
                switch (visibleTypeEnum) {
                    case NOT_SHOW_ANYONE:
                        // 不给谁编辑
                        return !ExplainUtil.notShowAnyOne(visibleRulePoJo, handlerExplainDTO);
                    case SOME_PEOPLE_CAN_SEE:
                        // 部分人可编辑
                        return !ExplainUtil.fieldCanSee(visibleRulePoJo, handlerExplainDTO);
                    default:
                        // TODO 存在没选的情况，暂时让可编辑（老字段会有此情况，新加字段没有此问题）
                        return true;
                }
            } else {
                // 未启用高级编辑规则 或 未设置高级编辑规则，可以编辑
                return true;
            }

        } else {
            return false;
        }
    }

    /**
     * 高级可见规则-不给谁看
     * @param visibleRulePoJo 高级可见规则
     * @param handlerExplainDTO 前端传参，主要获取当前登录的id和部门，角色
     * @return true：不可见；false：可见
     */
    public static Boolean notShowAnyOne(VisibleRulePoJo visibleRulePoJo, HandlerExplainDTO handlerExplainDTO) {

        List<Integer> relative = visibleRulePoJo.getRelative();
        List<VisibleRuleVO> department = visibleRulePoJo.getDep();
        List<Integer> role = visibleRulePoJo.getRole();
        List<String> userIds = visibleRulePoJo.getUser();
        UserVO userVO = handlerExplainDTO.getLoginUser();
        String userId = handlerExplainDTO.getUserId();
//        if (userVO.isAdminOrBoss()) {
//            return false;
//        }
        if (Objects.nonNull(relative) && !relative.isEmpty()) {
            Set<Integer> relativeSet = new HashSet<>(relative);
            // 创建者
            if (relativeSet.contains(RelatedPersonnelEnum.CREATOR.getType()) && Objects.nonNull(handlerExplainDTO.getCreatorId())
                    && Objects.equals(handlerExplainDTO.getCreatorId(), userId)) {
                return true;
            }
            // 负责人
            if (relativeSet.contains(RelatedPersonnelEnum.OWNER.getType()) && Objects.nonNull(handlerExplainDTO.getOwnerId())
                    && handlerExplainDTO.getOwnerId().contains(userId)) {
                return true;
            }
            // 协同人
            if (relativeSet.contains(RelatedPersonnelEnum.CO_USER.getType()) && Objects.nonNull(handlerExplainDTO.getCoUserId())
                    && handlerExplainDTO.getCoUserId().contains(userId)) {
                return true;
            }
        }
        if (checkDepartment(department, userVO) || checkRole(role, userVO) || (Objects.nonNull(userIds) && userIds.contains(userId))){
            return true;
        }
        return false;
    }

    private static boolean checkRole(List<Integer> role, UserVO userVO) {
        if (Objects.nonNull(role) && !role.isEmpty()) {
            Set<Integer> roleIdSet = new HashSet<>(role);
            Set<RoleSimpleVO> roleSet = userVO.getRoleSet();
            List<RoleSimpleVO> roleVOList = new ArrayList<>(roleSet);
            for (RoleSimpleVO roleVO : roleVOList) {
                if (roleIdSet.contains(roleVO.getId())) {
                    return true;
                }
            }
        }
        return false;
    }

    private static boolean checkDepartment(List<VisibleRuleVO> department, UserVO userVO) {
        if (Objects.nonNull(department) && !department.isEmpty()) {
            Set<Long> departmentIdSet = new HashSet<>();
            department.forEach(item->{
                departmentIdSet.add(Long.valueOf(item.getId().toString()));
            });
            Set<DepartmentVO> departmentSet = userVO.getDepSet();
            List<DepartmentVO> departmentVOList = new ArrayList<>(departmentSet);
            for (DepartmentVO item : departmentVOList) {
                if (departmentIdSet.contains(item.getId())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 高级可见规则-可见
     * @param visibleRulePoJo 高级可见规则
     * @param handlerExplainDTO 前端传参，主要获取当前登录的id和部门，角色
     * @return true：不可见；false：可见
     */
    public static Boolean fieldCanSee(VisibleRulePoJo visibleRulePoJo, HandlerExplainDTO handlerExplainDTO) {
        // 可见
        List<Integer> relative = visibleRulePoJo.getRelative();
        List<VisibleRuleVO> department = visibleRulePoJo.getDep();
        List<Integer> role = visibleRulePoJo.getRole();
        List<String> userIds = visibleRulePoJo.getUser();
        UserVO userVO = handlerExplainDTO.getLoginUser();
        String userId = handlerExplainDTO.getUserId();
//        if (userVO.isAdminOrBoss()) {
//            return false;
//        }
        if (Objects.nonNull(relative) && !relative.isEmpty()) {
            Set<Integer> relativeSet = new HashSet<>(relative);
            // 创建者
            if (relativeSet.contains(RelatedPersonnelEnum.CREATOR.getType())  && Objects.nonNull(handlerExplainDTO.getCreatorId())
                    && Objects.equals(userId, handlerExplainDTO.getCreatorId())) {
                return false;
            }
            // 负责人
            if (relativeSet.contains(RelatedPersonnelEnum.OWNER.getType()) && Objects.nonNull(handlerExplainDTO.getOwnerId())
                    && handlerExplainDTO.getOwnerId().contains(userId)) {
                return false;
            }
            // 协同人
            if (relativeSet.contains(RelatedPersonnelEnum.CO_USER.getType()) && Objects.nonNull(handlerExplainDTO.getCoUserId())
                    && handlerExplainDTO.getCoUserId().contains(userId)) {
                return false;
            }
        }
        if (Objects.nonNull(department) && !department.isEmpty()) {
            Set<Long> departmentIdSet = new HashSet<>();
            department.forEach(item->{
                departmentIdSet.add(Long.valueOf(item.getId().toString()));
            });
            Set<DepartmentVO> departmentSet = userVO.getDepSet();
            List<DepartmentVO> departmentVOList = new ArrayList<>(departmentSet);
            for (DepartmentVO item : departmentVOList) {
                if (departmentIdSet.contains(item.getId())) {
                    return false;
                }
            }
        }
        if (Objects.nonNull(role) && !role.isEmpty()) {
            Set<Integer> roleIdSet = new HashSet<>(role);
            Set<RoleSimpleVO> roleSet = userVO.getRoleSet();
            List<RoleSimpleVO> roleVOList = new ArrayList<>(roleSet);
            for (RoleSimpleVO roleVO : roleVOList) {
                if (roleIdSet.contains(roleVO.getId())) {
                    return false;
                }
            }
        }
        if(Objects.nonNull(userIds) && userIds.contains(userId)) {
            return false;
        }
        if (Objects.nonNull(relative) && !relative.isEmpty()) {
            Set<Integer> relativeSet = new HashSet<>(relative);
            if (relativeSet.contains(RelatedPersonnelEnum.CREATOR.getType()) && StringUtil.isEmpty(handlerExplainDTO.getCreatorId())) {
                return false;
            }
            if (relativeSet.contains(RelatedPersonnelEnum.OWNER.getType()) && CollectionsUtil.isEmpty(handlerExplainDTO.getOwnerId())) {
                return false;
            }
            if (relativeSet.contains(RelatedPersonnelEnum.CO_USER.getType()) && CollectionsUtil.isEmpty(handlerExplainDTO.getCoUserId())) {
                return false;
            }
        }
        return true;
    }
    //判断产品表单的'成本'字段的高级设置
    public static int costFieldInvisibleOfScope(FieldAttrEntity fieldAttrEntity,UserVO userVO){
        Integer visibleScopeEnable = fieldAttrEntity.getVisibleScopeEnable();
        // 高级可见规则回显用户名称
        VisibleRulePoJo visibleRulePoJo = fieldAttrEntity.getVisibleScopeRule();
        if (Objects.equals(1, visibleScopeEnable) && Objects.nonNull(visibleRulePoJo)) {
            Integer type = visibleRulePoJo.getType();
            VisibleTypeEnum visibleTypeEnum = VisibleTypeEnum.getByType(type);
            //负责人和创建人为空，判断有无成本字段的权限ExplainUtil.invisibleOfScope
            switch (visibleTypeEnum) {
                // 不给谁看
                case NOT_SHOW_ANYONE:
                    if (costFieldNotShowAnyOne(visibleRulePoJo, userVO)) {
                        //无权限时
                        //返回****
                        return 4;
                    }else{
                        //有权限判断是否选择了负责人或者创建人
                        if (CollectionUtils.isEmpty(fieldAttrEntity.getVisibleScopeRule().getRelative())) {
                            //没选负责人、创建人。-有权限，查询时不用管负责人、创建人
                            return 1;
                        }else{
                            //有权限时
                            //选了负责人、创建人。
                            //勾选了负责人或者创建人。-查询时要加上负责人或者创建人 负责人不等于该用户&&创建人不等于该用户
                            return 2;
                        }
                    }
                    // 部分人可见
                case SOME_PEOPLE_CAN_SEE:
                    if (costFieldCanSee(visibleRulePoJo, userVO)) {
                        //部分人可见无权限时
                        if (CollectionUtils.isEmpty(fieldAttrEntity.getVisibleScopeRule().getRelative())) {
                            //没选负责人、创建人。返回****
                            return 4;
                        }else{
                            //选了负责人、创建人。查询时要加上should条件，负责人、创建人等于一个就行
                            return 3;
                        }
                    }else{
                        //部分人可见有权限时
                        //查询时不用管负责人、创建人
                        return 1;
                    }
                default:
                    return 1;
            }
        } else {
            //没有勾选高级设置，查询时不用管负责人、创建人
            return 1;
        }
    }

    /**
     * @Description  判断成本字段可见性
     * @param visibleRulePoJo, userVO
     * @return java.lang.Boolean   无权限的话返回true,否则返回false
     * @author 魏铭
     * @Date  16:35
     * @since
     **/
    public static Boolean costFieldCanSee(VisibleRulePoJo visibleRulePoJo, UserVO userVO) {
        // 可见
        List<VisibleRuleVO> department = visibleRulePoJo.getDep();
        List<Integer> role = visibleRulePoJo.getRole();
        List<String> userIds = visibleRulePoJo.getUser();
        String userId = userVO.getUserId();
        //先判断该用户所在部门是否可见
        if (Objects.nonNull(department) && !department.isEmpty()) {
            Set<Long> departmentIdSet = new HashSet<>();
            department.forEach(item->{
                //可见的部门集合
                departmentIdSet.add(Long.valueOf(item.getId().toString()));
            });
            //该用户的部门以及父部门集合
            Set<DepartmentVO> departmentSet = userVO.getDepSet();
            List<DepartmentVO> departmentVOList = new ArrayList<>(departmentSet);
            for (DepartmentVO item : departmentVOList) {
                if (departmentIdSet.contains(item.getId())) {
                    return false;
                }
            }
        }
        //判断角色是否在可见范围内;可见的角色集合
        if (Objects.nonNull(role) && !role.isEmpty()) {
            Set<Integer> roleIdSet = new HashSet<>(role);
            Set<RoleSimpleVO> roleSet = userVO.getRoleSet();
            List<RoleSimpleVO> roleVOList = new ArrayList<>(roleSet);
            for (RoleSimpleVO roleVO : roleVOList) {
                //判断可见的角色集合是否包含该用户的角色
                if (roleIdSet.contains(roleVO.getId())) {
                    return false;
                }
            }
        }
        //判断用户是否包含该用户
        if(Objects.nonNull(userIds) && userIds.contains(userId)) {
            return false;
        }
        return true;
    }

    /**
     * @Description 判断成本字段，选择‘不给谁看’时的权限
     * @param visibleRulePoJo, userVO
     * @return java.lang.Boolean 无权限返回true，有权限返回false
     * @author 魏铭
     * @Date  16:37
     * @since
     **/
    public static Boolean costFieldNotShowAnyOne(VisibleRulePoJo visibleRulePoJo, UserVO userVO) {
        List<VisibleRuleVO> department = visibleRulePoJo.getDep();
        List<Integer> role = visibleRulePoJo.getRole();
        List<String> userIds = visibleRulePoJo.getUser();
        String userId = userVO.getUserId();
        if (checkDepartment(department, userVO) || checkRole(role, userVO) || (Objects.nonNull(userIds) && userIds.contains(userId))){
            return true;
        }
        return false;
    }

    /**
     * 设置表单字段编辑权限是否显示
     *
     * @param businessType 业务类型
     * @param explainList 表单字段解释列表
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-06-28 10:27
     * @since
     * @version
     */
    public static void setShowEditable(Integer businessType, List<FieldAttrEntity> explainList) {
        if(Objects.nonNull(explainList)) {
            for(FieldAttrEntity entity : explainList) {
                if (FieldTypeEnum.SUB_FORM.getType().equals(entity.getFieldType()) || FieldTypeEnum.CONTACT_NUMBER.getType().equals(entity.getFieldType())) {
                    List<? extends FieldAttrEntity> subExplainList = entity.getSubForm().getItems();
                    for(FieldAttrEntity subEntity: subExplainList) {
                        setShowEditable(subEntity);
                    }
                    entity.getSubForm().setItems(subExplainList);
                } else if (HideEditableEnum.getByType(businessType) != null && HideEditableEnum.getByType(businessType).contains(entity.getAttr())) {
                    entity.setShowEditable(BasicConstant.NO_USE);
                    continue;
                }
                if (XbbRefTypeEnum.hasVisibleRangeBusiness().contains(businessType) &&
                        (Objects.equals(entity.getAttr(), VisibleRangeEnum.VISIBLE_DEPT.getAttr()) || Objects.equals(entity.getAttr(), VisibleRangeEnum.VISIBLE_USER.getAttr()))) {
                    //跳过不进行处理,解释是啥就是啥
                    continue;
                }
                if (Objects.equals(businessType,XbbRefTypeEnum.PAYMENT.getCode()) && (Objects.equals(entity.getAttr(), PaymentEnum.OWNER_ID.getAttr()))) {
                    //特殊逻辑，把应收款的负责人字段放出来，然后把负责人字段这个字段属性不能进行任何处理
                    entity.setEditHide(BasicConstant.NO_USE);
                    entity.setVisibleAdvancedForbidden(BasicConstant.NO_USE);
                }
                if (Objects.equals(businessType,XbbRefTypeEnum.PAY_PLAN.getCode()) && (Objects.equals(entity.getAttr(), PayPlanEnum.OWNER_ID.getAttr()))) {
                    //特殊逻辑，把付款计划的负责人字段放出来，然后把负责人字段这个字段属性不能进行任何处理
                    entity.setVisible(BasicConstant.IS_USE);
                    entity.setIsForbidden(BasicConstant.NO_USE);
                    entity.setEditHide(BasicConstant.NO_USE);
                    entity.setVisibleAdvancedForbidden(BasicConstant.NO_USE);
                }
                setShowEditable(entity);
            }
        }
    }

    /**
     * 设置表单字段编辑权限是否显示
     *
     * @param businessType 业务类型
     * @param explainList 表单字段解释列表
     * @author long.rao
     * @date 2019-08-27 14:01
     */
    public static void setNoEditable(Integer businessType, List<FieldAttrEntity> explainList) {
        if(Objects.nonNull(explainList)) {
            if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                for(FieldAttrEntity entity : explainList) {
                    if (Objects.equals(entity.getAttr(), CustomerManagementEnum.TYPE.getAttr())) {

                    }
                }
            }
        }
    }

    /**
     * 设置表单字段编辑权限是否显示
     *
     * @param entity 表单字段
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-07-02 19:39
     * @since v1.0
     * @version v1.0
     */
    private static void setShowEditable(FieldAttrEntity entity) {
        FieldTypeEnum typeEnum = FieldTypeEnum.getFieldTypeEnum(entity.getFieldType());
        if ( Objects.isNull(typeEnum) ) {
            return;
        }
        switch (typeEnum) {
            // 表单字段编辑权限不显示：创建者、创建时间、更新时间
            case CREATORID:
            case UPDATETIME:
            case ADDTIME:
                entity.setShowEditable(BasicConstant.NO_USE);
                break;
                //协同人负责人 默认解释是什么样就是什么样 不进行处理
            case OWNERID:
            case COUSERID:
                break;
            default:
                entity.setShowEditable(Objects.isNull(entity.getShowEditable()) ? BasicConstant.IS_USE : entity.getShowEditable());
                break;
        }
    }

    /**
     * 判断是否子表单
     * @param type
     * @return ture ：是 false：否
     */
    public static Boolean isSubForm(Integer type) {
        return Objects.equals(FieldTypeEnum.SUB_FORM.getType(), type)
                || Objects.equals(FieldTypeEnum.CONTACT_NUMBER.getType(), type)
                || Objects.equals(FieldTypeEnum.SINGLE_SUB_FORM.getType(), type)
                ||Objects.equals(FieldTypeEnum.SWITCH_TEXT.getType(), type)
                ||Objects.equals(FieldTypeEnum.SELECT_SERVICE.getType(), type)
                || Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), type);
    }

    /**
     * 查重判断是否子表单
     * @param type
     * @return ture ：是 false：否
     */
    public static Boolean isSubFormDuplicate(Integer type) {
        return Objects.equals(FieldTypeEnum.SUB_FORM.getType(), type)
                || Objects.equals(FieldTypeEnum.CONTACT_NUMBER.getType(), type);
    }

    /**
     * 判断是否子表单
     * @param type
     * @return ture ：是 false：否
     */
    public static Boolean isSubFormNoSelectProduct(Integer type) {
        return Objects.equals(FieldTypeEnum.SUB_FORM.getType(), type)
                || Objects.equals(FieldTypeEnum.CONTACT_NUMBER.getType(), type)
                || Objects.equals(FieldTypeEnum.SINGLE_SUB_FORM.getType(), type)
                ||Objects.equals(FieldTypeEnum.SWITCH_TEXT.getType(), type);
    }
    /**
     * 判断是否是下拉框、单选按钮，复选按钮，下拉框复选
     * @param fieldType
     * @return ture ：是 false：否
     */
    public static Boolean isCombo(Integer fieldType) {
        if (Objects.equals(FieldTypeEnum.COMBO.getType(), fieldType) || Objects.equals(FieldTypeEnum.COMBO_CHECK.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.RADIO_GROUP.getType(), fieldType) || Objects.equals(FieldTypeEnum.CHECKBOX_GROUP.getType(), fieldType)) {
            return true;
        }
        return false;
    }

    public static Boolean isComboOrRadioGroup(Integer fieldType) {
        if (Objects.equals(FieldTypeEnum.COMBO.getType(), fieldType) || Objects.equals(FieldTypeEnum.RADIO_GROUP.getType(), fieldType)) {
            return true;
        }
        return false;
    }

    /**
     * 不要用这个方法
     * @param formDataList
     * @param corpid
     * @param operations
     * @return
     */
    @Deprecated
    public static List<UpdateDataEntity> getUpdateValueByBusinessRule(List<PaasFormDataEntityExt> formDataList,
                                                                      String corpid, List<OperationsPojo> operations) {
        return new ArrayList<>();
    }
    /**
     * 拼装需要更新的数据
     * @author 吴峰
     * @date 2019/9/24 15:09
     * @param formDataList 数据id列表
     * @param corpid 公司id
     * @param operations 操作方式列表
     * @return java.util.List<com.xbongbong.pro.domain.entity.UpdateDataEntity>
     * @throws XbbException 业务异常
     */
    public static List<UpdateDataEntity> getUpdateValueByBusinessRule(List<PaasFormDataEntityExt> formDataList,
                                                                      String corpid, List<OperationsPojo> operations, Map<String, FieldAttrEntity> explainMap) {
        if (operations.isEmpty() || CollectionsUtil.isEmpty(formDataList)) {
            return new ArrayList<>();
        }
        List<UpdateDataEntity> updateList = new ArrayList<>();
        Iterator<OperationsPojo> updateFieldIterator = operations.iterator();
        Map<String, OperationsPojo> updateFieldMap = new HashMap<>(operations.size());
        Map<String, OperationsPojo> updateSubFieldMap = new HashMap<>(operations.size());
        Map<String, FieldAttrEntity> subExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        while (updateFieldIterator.hasNext()) {
            OperationsPojo operationsPojo = updateFieldIterator.next();
            String key = operationsPojo.getAttr();
            if (key.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                // 获取子表单需要更新的字段
                List<String> attr = ExplainUtil.getAttrByPoint(key);
                updateSubFieldMap.put(attr.get(1), operationsPojo);
                updateFieldMap.put(attr.get(0), operationsPojo);
                if (subExplainMap.isEmpty()) {
                    subExplainMap = ExplainUtil.getExplainMap(JSON.toJSONString(explainMap.get(attr.get(0)).getSubForm().getItems()), null);
                }
            } else {
                updateFieldMap.put(key, operationsPojo);
            }
        }
        for (PaasFormDataEntityExt item : formDataList) {
            UpdateDataEntity updateDataEntity = new UpdateDataEntity();
            updateDataEntity.setId(item.getDataId());
            updateDataEntity.setCorpid(corpid);
            List<UpdateDataValueEntity> valueList = new ArrayList<>();
            JSONObject data = item.getData();
            Iterator<String> operationIterator = updateFieldMap.keySet().iterator();
            while (operationIterator.hasNext()) {
                OperationsPojo valueItem = updateFieldMap.get(operationIterator.next());
                String key = valueItem.getAttr();
                if (Objects.isNull(valueItem.getSubValue())) {
                    continue;
                }
                if (!valueItem.getSubValue().containsKey(item.getDataId())) {
                    continue;
                }
                if (key.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                    UpdateDataValueEntity updateDataValueEntity = new UpdateDataValueEntity();
                    List<String> targetList = ExplainUtil.getAttrByPoint(key);
                    key = targetList.get(0);
                    updateDataValueEntity.setKey(key);
                    updateDataValueEntity.setEsKey(key);
                    updateDataValueEntity.setDataType(DataTypeEnum.SUB_FORM.getDataType());
                    JSONArray subDataJson = data.getJSONArray(key);
                    if (!valueItem.getSubValue().containsKey(item.getDataId())) {
                        continue;
                    }

                    JSONArray resultArray = JSON.parseArray(JSON.toJSONString(valueItem.getSubValue().get(item.getDataId())));
                    if (Objects.nonNull(subDataJson) && Objects.nonNull(resultArray) && subDataJson.size() == resultArray.size()) {
                        // 必须保证源数据和更新的数据是一样的大小；
                        List<UpdateSubDataEntity> subDataList = new ArrayList<>();

                        for (int i = 0; i < subDataJson.size(); i++) {
                            UpdateSubDataEntity updateSubDataEntity = new UpdateSubDataEntity();
                            JSONObject subValueJson = subDataJson.getJSONObject(i);
                            updateSubDataEntity.setSubDataId(subValueJson.getLong(BusinessConstant.SUB_DATA_ID));
                            updateSubDataEntity.setParentId(item.getParentId());
                            Iterator<String> iterator = subValueJson.keySet().iterator();
                            List<UpdateDataValueEntity> subValueList = new ArrayList<>();
                            while (iterator.hasNext()) {
                                // 不需要更新的值，拿原数据
                                String subKey = iterator.next();
                                if (!updateSubFieldMap.containsKey(subKey)) {
                                    FieldAttrEntity fieldAttrEntity = subExplainMap.get(subKey);
                                    Object subValue = subValueJson.get(subKey);
                                    String dataType = "";
                                    if (subValue instanceof JSONArray || subValue instanceof ArrayList || subValue instanceof List || FieldTypeEnum.isArray(fieldAttrEntity.getFieldType())) {
                                        dataType = DataTypeEnum.JSON_ARRAY.getDataType();
                                        if (subValue == null) {
                                            subValue = new ArrayList<>();
                                        }
                                    } else if (subValue instanceof Map || FieldTypeEnum.isJsonObject(fieldAttrEntity.getFieldType())) {
                                        dataType = DataTypeEnum.JSON_OBJECT.getDataType();
                                    }
                                    UpdateDataValueEntity updateSubDataValueEntity = new UpdateDataValueEntity(subKey, subKey, subValue, dataType, null);
                                    subValueList.add(updateSubDataValueEntity);
                                }
                            }
                            Iterator<String> updateSubField = updateSubFieldMap.keySet().iterator();
                            while (updateSubField.hasNext()) {
                                String subKey = updateSubField.next();
                                if (updateSubFieldMap.containsKey(subKey)) {
                                    // 获取需要更新的值
                                    FieldAttrEntity fieldAttrEntity = subExplainMap.get(subKey);
                                    OperationsPojo operationsPojo = updateSubFieldMap.get(subKey);
                                    JSONArray updateJson = JSON.parseArray(JSON.toJSONString(operationsPojo.getSubValue().get(item.getDataId())));
                                    JSONObject resultValueJson = updateJson.getJSONObject(i);
                                    Object subValue = resultValueJson.get(subKey);
                                    String dataType = "";
                                    if (subValue instanceof JSONArray || subValue instanceof ArrayList || subValue instanceof List || FieldTypeEnum.isArray(fieldAttrEntity.getFieldType())) {
                                        dataType = DataTypeEnum.JSON_ARRAY.getDataType();
                                        if (subValue == null) {
                                            subValue = new ArrayList<>();
                                        }
                                    } else if (subValue instanceof Map || FieldTypeEnum.isJsonObject(fieldAttrEntity.getFieldType())) {
                                        dataType = DataTypeEnum.JSON_OBJECT.getDataType();
                                    }
                                    UpdateDataValueEntity updateSubDataValueEntity = new UpdateDataValueEntity(subKey, subKey, subValue, dataType, null);
                                    subValueList.add(updateSubDataValueEntity);
                                }
                            }
                            if (CollectionsUtil.isEmpty(subValueList)) {
                                continue;
                            }
                            updateSubDataEntity.setSubDataList(subValueList);
                            subDataList.add(updateSubDataEntity);
                        }
                        updateDataValueEntity.setSubDataList(subDataList);
                        valueList.add(updateDataValueEntity);
                    }
                } else {
                    boolean isArray = FieldTypeEnum.isArray(valueItem.getFieldType());
                    UpdateDataValueEntity updateDataValueEntity = new UpdateDataValueEntity();
                    updateDataValueEntity.setKey(key);
                    updateDataValueEntity.setEsKey(key);
                    Object value = valueItem.getSubValue().get(item.getDataId());
                    boolean isList = value instanceof JSONArray || value instanceof ArrayList || value instanceof List || isArray;
                    if (isList) {
                        updateDataValueEntity.setDataType(DataTypeEnum.JSON_ARRAY.getDataType());
                        if (value == null) {
                            value = new ArrayList<>();
                        }
                    } else if (value instanceof Map || value instanceof JSONObject || FieldTypeEnum.isJsonObject(valueItem.getFieldType())) {
                        updateDataValueEntity.setDataType(DataTypeEnum.JSON_OBJECT.getDataType());
                    }
                    updateDataValueEntity.setValue(value);
                    valueList.add(updateDataValueEntity);
                }
            }
            if (CollectionsUtil.isNotEmpty(valueList)) {
                updateDataEntity.setData(valueList);
                long now = DateUtil.getInt();
                updateDataEntity.setUpdateTime(now);
                updateList.add(updateDataEntity);
            }
        }
        return updateList;
    }

    /**
     * 字段需要隐藏
     * @author long.rao
     * @date 2019-10-30 15:08
     * @param fieldAttrEntity 产品字段容器
     * @param handlerExplainDTO 前端参数
     * @return java.lang.Boolean ture:隐藏；false：不隐藏
     * @throws XbbException 业务异常
     */
    public static Boolean fieldAttrHide(FieldAttrEntity fieldAttrEntity, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        if(Objects.equals(fieldAttrEntity.getIsOpen(), 1) && Objects.equals(fieldAttrEntity.getVisible(), 1)) {
            return invisibleOfScope(fieldAttrEntity, handlerExplainDTO);
        } else {
            return true;
        }
    }

    /**
     * 获取下拉项
     * @author long.rao
     * @date 2019-10-30 15:08
     * @param explainMap 产品字段容器
     * @param attr
     * @throws XbbException 业务异常
     */
    public static Map<String, String> getItemsMap(Map<String, FieldAttrEntity> explainMap, String attr) throws XbbException {
        FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
        Map<String, String> itemsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (Objects.nonNull(fieldAttrEntity) && Objects.nonNull(fieldAttrEntity.getItems())) {
            List<ItemPoJo> itemPoJos = fieldAttrEntity.getItems();
            itemPoJos.forEach(item-> itemsMap.put(item.getValue().toString(), item.getText()));
        }
        return itemsMap;
    }

    /**
     * List<UpdateDataValueEntity> 转回JSONObject类型
     * @param updateDataEntityList 入参
     * @return JSONObject
     */
    public static JSONObject getDataJsonByUpdateDataValue(List<UpdateDataValueEntity> updateDataEntityList) {
        JSONObject result = new JSONObject();
        if (updateDataEntityList != null && updateDataEntityList.size() > 0) {
            updateDataEntityList.forEach(e -> {
                String key = e.getKey();
                String resultKey = key.replace("$.", "");
                result.put(resultKey, e.getValue());
            });
        }
        return result;
    }

    public static List<String> getAttrByPoint(String attr) {
        if (StringUtil.isEmpty(attr)) {
            return new ArrayList<>();
        }
        List<String> list = new ArrayList<>();
        if (attr.contains(".")) {
            list = Arrays.asList(attr.split("\\."));
        }
        return list;
    }

    public static Boolean isUser(Integer fieldType) {
        return Objects.equals(FieldTypeEnum.USER.getType(), fieldType) || Objects.equals(FieldTypeEnum.USER_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.OWNERID.getType(), fieldType) || Objects.equals(FieldTypeEnum.COUSERID.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.CREATORID.getType(), fieldType);
    }

    public static Boolean isDept(Integer fieldType) {
        return Objects.equals(FieldTypeEnum.DEPT.getType(), fieldType) || Objects.equals(FieldTypeEnum.DEPT_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.DEPARTMENTID.getType(), fieldType);
    }

    /**
     * 通用过滤外链的字段
     * @param attrEntities
     * @param type
     * @param internalSubform 是否从内部子表单调用
     * @param
     * @return
     */
    public static void filterSpecialAttr(List<FieldAttrEntity> attrEntities, Integer type, Integer internalSubform) {
        if (CollectionsUtil.isEmpty(attrEntities)) {
            return ;
        }
        // 外链表单会过滤“选人控件、选部门控件、创建人、负责人，所属部门，关联数据、关联数据多选、数据联动字段、定位控件,标签、手签”
        List<Integer> outerLinkRemoveAttr = Arrays.asList(FieldTypeEnum.SELECT_DEPARTMENT.getType(), FieldTypeEnum.LINK_QUERY.getType(), FieldTypeEnum.LINK_DATA.getType(), FieldTypeEnum.LINK_DATA_MULTI.getType(),
                FieldTypeEnum.USER.getType(), FieldTypeEnum.USER_GROUP.getType(), FieldTypeEnum.DEPT.getType(), FieldTypeEnum.DEPT_GROUP.getType(), FieldTypeEnum.CREATORID.getType(),
                FieldTypeEnum.DEPARTMENTID.getType(), FieldTypeEnum.OWNERID.getType(), FieldTypeEnum.COUSERID.getType(), FieldTypeEnum.WAREHOUSE_ID.getType(),
                FieldTypeEnum.TEAM_USER.getType(), FieldTypeEnum.COPY_USER.getType(), FieldTypeEnum.LINK_BUSINESS_SINGLE.getType(), FieldTypeEnum.LINK_BUSINESS_MULTI.getType(),
                FieldTypeEnum.LINK_BUSINESS_COMBO.getType(), FieldTypeEnum.LINK_FORM.getType(), FieldTypeEnum.PRE_OWNER_ID.getType(), FieldTypeEnum.LOCATION.getType(),
                FieldTypeEnum.SELECT_PRODUCT.getType(), FieldTypeEnum.LINK_FORM_BUTTON.getType(),FieldTypeEnum.VIDEO.getType(),FieldTypeEnum.MANUAL_SIGN.getType(),FieldTypeEnum.TEMPLATE_FIELD.getType());
        Iterator<FieldAttrEntity> iterator = attrEntities.iterator();
        while (iterator.hasNext()) {
            FieldAttrEntity fieldAttrEntity = iterator.next();
            Integer fieldType = fieldAttrEntity.getFieldType();
            DefaultAttrPoJo defaultAttr = fieldAttrEntity.getDefaultAttr();
            Integer comboType = fieldAttrEntity.getComboType();
            if (outerLinkRemoveAttr.contains(fieldAttrEntity.getFieldType())) {
                iterator.remove();
                continue;
            }
            //没有启用就把这个字段移除调
            if ( Objects.equals(fieldAttrEntity.getIsOpen(),0) || Objects.equals(fieldAttrEntity.getIsOpen(), 2)) {
                iterator.remove();
                continue;
            }
            if(isSubForm(fieldType)){
                List<? extends FieldAttrEntity> subFieldAttr = fieldAttrEntity.getSubForm().getItems();
                filterSpecialAttr((List<FieldAttrEntity>) subFieldAttr, type, BasicConstant.ONE);
                if (CollectionsUtil.isEmpty(subFieldAttr)) {
                    // 如果子表单的项空了，那么直接把这个子表单字段去掉
                    iterator.remove();
                    continue;
                }
            }
            if (Objects.equals(type, OuterLinkTypeEnum.WRITE.getCode())) {
                if (!ShowTypeEnum.editShow(fieldAttrEntity.getShowType()) && Objects.isNull(internalSubform)){
                    iterator.remove();
                    continue;
                }
                if (Objects.equals(fieldType, FieldTypeEnum.ADDTIME.getType()) || Objects.equals(fieldType, FieldTypeEnum.UPDATETIME.getType())) {
                    iterator.remove();
                    continue;
                }
//                LinkFormPoJo linkForm = fieldAttrEntity.getLinkForm();
//                if (Objects.nonNull(linkForm) && Objects.nonNull(linkForm.getSourceFormId())) {
//                    // 如果关联了其它表单，则直接移除
//                    iterator.remove();
//                    continue;
//                }
            } else if (Objects.equals(type, OuterLinkTypeEnum.SEARCH.getCode())) {
                if (!ShowTypeEnum.listShow(fieldAttrEntity.getShowType()) && Objects.isNull(internalSubform)){
                    iterator.remove();
                    continue;
                }
                if (Objects.equals(fieldType, FieldTypeEnum.IMAGE.getType())
                        || Objects.equals(fieldType, FieldTypeEnum.UPLOAD.getType())
                        || Objects.equals(fieldType, FieldTypeEnum.VIDEO.getType())
                        || Objects.equals(fieldType, FieldTypeEnum.SEPARATOR.getType())) {
                    iterator.remove();
                    continue;
                }
//                if (isSubFormNoSelectProduct(fieldType)) {
//                    List<FieldAttrEntity> subExplainList = JSONObject.parseArray(JSON.toJSONString(fieldAttrEntity.getSubForm().getItems()), FieldAttrEntity.class);
//                    filterSpecialAttr(subExplainList, type);
//                }
            } else if (Objects.equals(type, OuterLinkTypeEnum.SHARE.getCode())) {
                if (!ShowTypeEnum.detailShow(fieldAttrEntity.getShowType()) && Objects.isNull(internalSubform)){
                    iterator.remove();
                    continue;
                }
                if (Objects.equals(fieldType, FieldTypeEnum.ADDTIME.getType()) || Objects.equals(fieldType, FieldTypeEnum.UPDATETIME.getType())) {
                    iterator.remove();
                    continue;
                }
            }
            if (Objects.equals(comboType, ComboTypeEnum.DATARELY.getType()) || Objects.equals(comboType, ComboTypeEnum.LINKFORM.getType()) || Objects.equals(comboType, ComboTypeEnum.BUSINESS.getType())) {
                iterator.remove();
                continue;
            }
            if (Objects.nonNull(defaultAttr)) {
                if (StringUtil.isNotEmpty(defaultAttr.getDefaultType())) {
                    String defaultType = defaultAttr.getDefaultType();
                    if (Objects.equals(defaultType, DefaultTypeEnum.CUSTOM.getAlias()) || Objects.equals(defaultType, DefaultTypeEnum.TODAY.getAlias()) || Objects.equals(defaultType, DefaultTypeEnum.FORMULA.getAlias())) {
                        continue;
                    }
                    // 外链不需要这些特殊的表单设置规则
                    DefaultAttrPoJo defaultAttrPoJo = new DefaultAttrPoJo();
                    defaultAttrPoJo.setDefaultType(DefaultTypeEnum.CUSTOM.getAlias());
                    fieldAttrEntity.setDefaultAttr(defaultAttrPoJo);
                }
                if (Objects.nonNull(defaultAttr.getBusinessMatchAttr())) {
                    // 外链不需要工商查询
                    iterator.remove();
                    continue;
                }
                /*if (Objects.nonNull(defaultAttr.getRely())) {
                    RelyPoJo rely = defaultAttr.getRely();
                    if (Objects.nonNull(rely) && Objects.nonNull(rely.getSourceFormId())) {
                        iterator.remove();
                        continue;
                    }
                }*/
            }
            fieldAttrEntity.setLinkForm(new LinkFormPoJo());
            if (Objects.equals("extensionField",fieldAttrEntity.getSaasAttr())){
                iterator.remove();
            }
        }
    }

    /**
     * 外链查询处理可见可编辑
     * @param attrEntities
     * @param
     * @param
     * @return
     */
    public static void handelFieldPermission(List<FieldAttrEntity> attrEntities, OuterLinkConfigEntity permissionConfig, OuterLinkConfigEntity displayConfig) throws XbbException{
        if (CollectionsUtil.isEmpty(attrEntities)) {
            return ;
        }
        Map<String, OutLinkFieldAttrEntity> permissionExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (Objects.nonNull(permissionConfig)) {
            List<OutLinkFieldAttrEntity> fieldList = JSONArray.parseArray(permissionConfig.getExplains(), OutLinkFieldAttrEntity.class);
            permissionExplainMap = BeanUtil.convertListToMap(fieldList, "attr");
        }
        Map<String, OutLinkFieldAttrEntity> displayExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (Objects.nonNull(displayConfig)) {
            List<OutLinkFieldAttrEntity> fieldList = JSONArray.parseArray(displayConfig.getExplains(), OutLinkFieldAttrEntity.class);
            displayExplainMap = BeanUtil.convertListToMap(fieldList, "attr");
        }
        handlerSearchPermission(attrEntities, permissionExplainMap, displayExplainMap);
    }

    private static void handlerSearchPermission(List<FieldAttrEntity> fieldAttrEntities, Map<String, OutLinkFieldAttrEntity> permissionExplainMap, Map<String, OutLinkFieldAttrEntity> displayExplainMap) throws XbbException{
        Iterator<FieldAttrEntity> iterator = fieldAttrEntities.iterator();
        while (iterator.hasNext()) {
            FieldAttrEntity fieldAttrEntity = iterator.next();
            Integer fieldType = fieldAttrEntity.getFieldType();
            OutLinkFieldAttrEntity permissionEntity = permissionExplainMap.get(fieldAttrEntity.getAttr());
            OutLinkFieldAttrEntity displayEntity = displayExplainMap.get(fieldAttrEntity.getAttr());
            if (isSubForm(fieldType)) {
                List<? extends FieldAttrEntity> items = fieldAttrEntity.getSubForm().getItems();
                Map<String, ? extends OutLinkFieldAttrEntity> subPermissionMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<String, ? extends OutLinkFieldAttrEntity> subDisplayMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                if (Objects.nonNull(permissionEntity) && Objects.nonNull(permissionEntity.getSubForm())) {
                    List<? extends OutLinkFieldAttrEntity> itemsList = permissionEntity.getSubForm().getItems();
                    if (CollectionsUtil.isNotEmpty(itemsList)) {
                        subPermissionMap = BeanUtil.convertListToMap(itemsList, "attr");
                    }
                }
                if (Objects.nonNull(displayEntity) && Objects.nonNull(displayEntity.getSubForm())) {
                    List<? extends OutLinkFieldAttrEntity> itemsList = displayEntity.getSubForm().getItems();
                    if (CollectionsUtil.isNotEmpty(itemsList)) {
                        subDisplayMap = BeanUtil.convertListToMap(itemsList, "attr");
                    }
                }
                if (CollectionsUtil.isNotEmpty(items)) {
                    Iterator<? extends FieldAttrEntity> subIteeator = items.iterator();
                    while (subIteeator.hasNext()) {
                        FieldAttrEntity next = subIteeator.next();
                        OutLinkFieldAttrEntity subPermissionEntity = subPermissionMap.get(next.getAttr());
                        OutLinkFieldAttrEntity subDisplayEntity = subDisplayMap.get(next.getAttr());
                        if (Objects.nonNull(subPermissionEntity)) {
                            Integer visible = subPermissionEntity.getVisible();
                            if (Objects.equals(visible, BasicConstant.ONE)) {
                                next.setVisible(BasicConstant.ONE);
                            } else {
                                subIteeator.remove();
                            }
                        } else {
                            next.setVisible(BasicConstant.ONE);
                        }
                        next.setVisibleScopeEnable(BasicConstant.ZERO);
                        if (Objects.nonNull(subDisplayEntity)) {
                            next.setAttrName(subDisplayEntity.getDefaultName());
                        }
                    }
                }
            }
            if (Objects.nonNull(permissionEntity)) {
                Integer visible = permissionEntity.getVisible();
                if (Objects.equals(visible, BasicConstant.ONE)) {
                    fieldAttrEntity.setVisible(BasicConstant.ONE);
                } else {
                    iterator.remove();
                    continue;
                }
            } else {
                fieldAttrEntity.setVisible(BasicConstant.ONE);
            }
            fieldAttrEntity.setVisibleScopeEnable(BasicConstant.ZERO);
            if (Objects.nonNull(displayEntity) && StringUtil.isNotEmpty(displayEntity.getDefaultName())) {
                fieldAttrEntity.setAttrName(displayEntity.getDefaultName());
            }
            if ( Objects.equals(fieldAttrEntity.getIsOpen(),0) ) {
                iterator.remove();
                continue;
            }
        }
    }


    public static Boolean isWorkReport(Integer businessType) {
        return Objects.equals(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), businessType) || Objects.equals(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), businessType)
                || Objects.equals(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), businessType)
                ;
    }

    /**
     * 判断电话字段是否开启电话掩码功能
     * @param fieldAttrEntity 电话字段entity
     * @return
     */
    public static boolean isOpenTelephoneMask(FieldAttrEntity fieldAttrEntity, UserVO loginUser) {
        try {
            //客户管理、联系人、供应商、供应商联系人、销售出库单、市场线索、工单、工单出库单
            boolean isContactField = isSystemPhoneField(fieldAttrEntity);
            if (!isContactField) {
                return false;
            }
            //老板和管理员不受电话掩码影响
            if (Objects.isNull(loginUser) || loginUser.isAdminOrBoss()) {
                return false;
            }
            SubFormPoJo subForm = fieldAttrEntity.getSubForm();
            boolean isOpenTelephoneMask = false;
            List<? extends FieldAttrEntity> items = subForm.getItems();
            if (CollectionsUtil.isNotEmpty(items)) {
                for (FieldAttrEntity item : items) {
                    if (Objects.equals(item.getSaasAttr(), ContactEnum.PHONE.getSaasAttr())) {
                        if (Objects.equals(item.getIsMaskTelephone(), BasicConstant.ONE)) {
                            isOpenTelephoneMask = true;
                        }
                    }
                }
            }
            return isOpenTelephoneMask;
        } catch (Exception e) {
            LOG.error("ExplainUtil.isOpenTelephoneMask方法出错", e);
            return false;
        }
    }

    /**
     * 判断是否系统表单的电话字段
     *
     * @param fieldAttrEntity 字段解释
     * @return
     */
    public static boolean isSystemPhoneField(FieldAttrEntity fieldAttrEntity) {
        return Objects.nonNull(fieldAttrEntity) && (Objects.equals(fieldAttrEntity.getSaasAttr(), ContactEnum.PHONE.getSaasAttr())
                || Objects.equals(fieldAttrEntity.getSaasAttr(), WorkOrderEnum.CONTACT_INFORMATION.getSaasAttr())
                || Objects.equals(fieldAttrEntity.getSaasAttr(), ContractOutstockEnum.CUSTOMER_PHONE.getSaasAttr()));
    }

    /**
     * description: 获取阶段推进器字段
     * date: 2021/12/9 4:09 下午
     *
     * @author yingjf
     */
    public static FieldAttrEntity getPassStageAttr(PaasFormExplainEntity explain) throws XbbException {
        List<FieldAttrEntity> fieldList = JSONArray.parseArray(explain.getExplains(), FieldAttrEntity.class);
        return fieldList.stream().filter(fieldAttrEntity -> Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType())).findFirst().orElse(null);
    }

    /**
     * description:  校验字段编辑权限
     * date: 2021/12/8 7:40 下午
     *
     * @Author yingjf
     */
    public static boolean isStageEdit(String attr, Map<String, FieldAttrEntity> explainMap, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
        if (fieldAttrEntity == null) {
            return false;
        }
        // 是否启用字段
        if (!Objects.equals(fieldAttrEntity.getIsOpen(), 1)) {
            return false;
        }
        try {
            // 判断是否可编辑
            return ExplainUtil.isEditableOfScope(fieldAttrEntity, handlerExplainDTO);
        } catch (XbbException e) {
            LOG.error("com.xbongbong.paas.service.stage.execute.AbstractStageExecuteHandle.isStageEdit", e);
        }
        return false;
    }
}
